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 component
  • SimpleMixture — multi-component (mixtures)
  • SimpleChargedFluidone-component plasma (OCP): a single mobile charged species in a uniform neutralizing background
  • SimpleChargedMixture — electrolyte mixture: multiple mobile charged species (no background; must be electroneutral)
Choosing a system
TypeComponentsρ (density) inputevaluate_potential return
SimpleFluid1NumberNumber
SimpleMixture≥ 2AbstractVector (length = Ns)Ns×Ns matrix (e.g. SMatrix)
SimpleChargedFluid1 + 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.SimpleFluidType
SimpleFluid{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)
source

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.SimpleMixtureType
SimpleMixture{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 with StaticArrays.SVector storage (as before).
  • evaluate_potential(potential, r) must return an Ns×Ns matrix (e.g., StaticArrays.SMatrix{Ns,Ns}).
source
Note

The density vector ρ::AbstractVector is converted to Diagonal(SVector{Ns}(ρ)) internally.

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.SimpleChargedFluidType
SimpleChargedFluid{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
source

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.SimpleChargedMixtureType
SimpleChargedMixture{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
source

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 length Ns, then evaluate_potential(potential, r) must return an Ns×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.