Tutorial

This tutorial walks through building a complete particle population simulation with all four physics processes.

Setting Up the Particle System

Each particle is represented as an SVector{A, Float64} where A is the number of chemical species. For a single-species system:

julia> n_sim = 5050
julia> # Initial particles: each with 1 fg of mass particles = fill(SVector(1.0e-15), n_sim)50-element Vector{StaticArraysCore.SVector{1, Float64}}: [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] ⋮ [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15] [1.0e-15]

Defining Physics Processes

Condensation (ODE Drift)

Condensation provides continuous growth via an ODE drift term:

julia> cond = CondensationProcess((μ, g, t) -> -0.01 .* μ)CondensationProcess{Main.var"#2#3"}(Main.var"#2#3"())

The flux function (μ, g, t) -> SVector receives the particle state μ, gas-phase concentration g(t), and time t.

Coagulation (Stochastic Jump)

Brownian coagulation uses the diffusion kernel with majorant sampling:

julia> kernel = BrownianKernel(293.15, 101325.0, SVector(1800.0))  # T, p, ρBrownianKernel{1}(293.15, 101325.0, 1.2040972472143983, 1.8177820338749172e-5, 1.5096638067068415e-5, 462.91108601708453, 6.522478516105898e-8, [1800.0], 1.380649e-23)
julia> coag = CoagulationProcess(kernel, GlobalMajorant())CoagulationProcess{BrownianKernel{1}, GlobalMajorant}(BrownianKernel{1}(293.15, 101325.0, 1.2040972472143983, 1.8177820338749172e-5, 1.5096638067068415e-5, 462.91108601708453, 6.522478516105898e-8, [1800.0], 1.380649e-23), GlobalMajorant())

When two particles coagulate, the package uses CNMC (Constant Number Monte Carlo) to maintain the particle count: merge + clone + volume rescale.

Emission (Stochastic Jump)

New particles are injected via a Poisson process:

julia> emit = EmissionProcess(0.1, t -> SVector(1.0e-15))EmissionProcess{Main.var"#5#6"}(0.1, Main.var"#5#6"())

The first argument is the total emission rate; the second is a sampler function t -> SVector{A}.

Dilution (Stochastic Jump)

Dilution removes random particles and injects background particles:

julia> dil = DilutionProcess(t -> 0.05, t -> SVector(0.5e-15))DilutionProcess{Main.var"#9#10", Main.var"#11#12"}(Main.var"#9#10"(), Main.var"#11#12"())

First argument: dilution rate λ(t). Second argument: background particle sampler.

Assembling and Solving

Combine all processes into a ParticleProblem and solve:

julia> gas_fn = t -> SVector(0.0)#14 (generic function with 1 method)
julia> prob = ParticleProblem(particles, 1.0, gas_fn, (cond, coag, emit, dil); tspan=(0.0, 5.0), n_sim=n_sim)JumpProblem with problem ODEProblem with aggregator JumpProcesses.Direct Number of jumps with discrete aggregation: 4 Number of jumps with continuous aggregation: 0 Number of mass action jumps: 0
julia> sol = solve(prob, Tsit5())retcode: Success Interpolation: specialized 4th order "free" interpolation t: 39-element Vector{Float64}: 0.0 9.999999999999999e-5 0.26618040624240685 0.26618040624240685 0.4387288529061646 0.4387288529061646 1.1264186508072938 1.1264186508072938 1.840282260456275 1.840282260456275 ⋮ 4.2736547149712285 4.2736547149712285 4.4447055929542065 4.4447055929542065 4.592393443045275 4.592393443045275 4.680054180653694 4.680054180653694 5.0 u: 39-element Vector{Vector{Float64}}: [1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15 … 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15, 1.0e-15] [9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16 … 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16, 9.999990000005e-16] [9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16 … 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16] [9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16 … 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16, 9.973417353968637e-16] [9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16 … 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16 … 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16 … 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16 … 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16 … 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16 … 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] ⋮ [9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16, 9.58163787799058e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16, 9.565262411457434e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16, 9.551146107645029e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16, 9.542777171188642e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16] [9.512294245007141e-16, 9.512294245007141e-16, 9.512294245007141e-16, 9.512294245007141e-16, 9.512294245007141e-16, 9.512294245007141e-16, 9.512294245007141e-16, 9.512294245007141e-16, 9.512294245007141e-16, 9.512294245007141e-16 … 9.692172138732468e-16, 9.698060586078624e-16, 9.737640139081484e-16, 9.793257919916058e-16, 9.810412394466952e-16, 9.81531711803341e-16, 9.817654753681434e-16, 9.887990169064954e-16, 9.956223215620394e-16, 9.973417353968637e-16]

The returned sol is a standard SciML solution object.

Computing Diagnostics

julia> sys = prob.prob.pParticleSystem{1, Main.var"#14#15"}(33, 1.0, Main.var"#14#15"(), 50, 0.0, 6.687438960046552e-16)
julia> A_val = species_val(sys)Val{1}()
julia> u_final = sol.u[end]50-element Vector{Float64}: 9.512294245007141e-16 9.512294245007141e-16 9.512294245007141e-16 9.512294245007141e-16 9.512294245007141e-16 9.512294245007141e-16 9.512294245007141e-16 9.512294245007141e-16 9.512294245007141e-16 9.512294245007141e-16 ⋮ 9.698060586078624e-16 9.737640139081484e-16 9.793257919916058e-16 9.810412394466952e-16 9.81531711803341e-16 9.817654753681434e-16 9.887990169064954e-16 9.956223215620394e-16 9.973417353968637e-16
julia> n0 = number_concentration(sys)50.0
julia> M = mass_concentration(u_final, A_val, sys)3.1390571008523564e-14
  • number_concentration(sys) — zeroth moment [particles/m³]
  • mass_concentration(u, Val(A), sys) — first moment [kg/m³]
  • species_mass_concentration(u, idx, Val(A), sys) — single-species mass [kg/m³]