Forward Models
Single DMA
Constant Voltage
The DMA is operated in classifier mode and set to a single voltage. The mobility classified particles are then passed to one or more detectors. Transmission can be modeled by the convolution of the particle Charging Probability, DMA Transfer Function, and Transmission Loss through the DMA. These are built into the DMA Grid. Therefore a net transmission function can be written:
The net transmission function T describes transmission through the DMA, including the charge filter, the DMA transfer function, and the DMA transmission efficiency.
T(zˢ,k,Λ,δ) = δ.Ω(Λ,δ.Z,zˢ/k).*δ.Tc(k,δ.Dp).*δ.Tl(Λ,δ.Dp)
where Λ is the DMA configuration, δ the DMA grid, zˢ is the z-star selected by the DMA, and k is the number of charges.
The following example shows ho to use T(zˢ,k,Λ,δ) to predict the mobility distribution exiting the DMA. In the code fragment
- zˢ is the z-star selected by the DMA
- 𝕟ᶜⁿ is an assumed known bimodal lognormal distribution computed on the DMA size grid
- ℕ is an array of transmitted mobility distributions carrying k charges
- 𝕄 is an array of transmitted apparent mobility distributions carrying k charges
- 𝕟ₜ, 𝕞ₜ are the superposition of these distributions
using DifferentialMobilityAnalyzers
# Create a DMA config
qsa,qsh = 1.66e-5, 8.33e-5 # Qsample [m3 s-1], Qsheath [m3 s-1]
t,p = 295.15, 1e5 # Temperature [K], Pressure [Pa]
r₁,r₂,l = 9.37e-3,1.961e-2,0.44369 # DMA geometry [m]
Λ = DMAconfig(t,p,qsa,qsh,r₁,r₂,l,0.0,:-,6,:cylindrical)
# Create a DMA grid
z₁,z₂ = vtoz(Λ,10000), vtoz(Λ,10) # bins, upper, lower mobility limit
δ = setupDMA(Λ, z₁, z₂, 512);
# Compute the transmission through the DMA
T(zˢ,k,Λ,δ) = δ.Ω(Λ,δ.Z,zˢ/k).*δ.Tc(k,δ.Dp).*δ.Tl(Λ,δ.Dp)
zˢ = dtoz(Λ, 100*1e-9)
𝕟ᶜⁿ = DMALognormalDistribution([[900., 40., 1.5], [500., 180., 1.4]], δ)
ℕ = map(k -> T(zˢ,k,Λ,δ)*𝕟ᶜⁿ,1:3)
𝕄 = map(k -> (ztod(Λ,1,zˢ)/ztod(Λ,k,zˢ))⋅(T(zˢ,k,Λ,δ)*𝕟ᶜⁿ),1:3)
𝕟ₜ, 𝕞ₜ = sum(ℕ), sum(𝕄)
Figure. Left: assumed bimodal lognormal size distribution. Middle: monodisperse mobility size distribution plotted against the apparent +1 mobility diameter, defined as the apparent setpoint diameter of the DMA. Dashed line is total number concentration. Right: same as middle panel but plotted versus the mobility diameter.
The DMA selects approximately a triangular distribution around mobility centroid $z^s$. The distribution is symmetric when plotted against the log of mobility, but asymmetric when plotted against the log of the apparent +1 mobility diameter because the Cunningham slip flow correction factor applied in the conversion from mobility to diameter is a strong function of particle size. The majority of selected particles are singly charged, but the contribution of multiply charged particles to the total number is not negligible. The mobility distribution has contributions from particles that are at least twice the diameter of the selected centroid diameter. The relative fractions are determined by the equilibrium charge fraction and the number of particles available at each diameter.
The map(k->f, 1:3)
construct sequentially applies values from the array [1,2,3] to k and calls the function f. The output is an array of length 3. Since T(zˢ,k,Λ,δ)
produces a vector, 𝕟ᶜⁿ is a size distribution, and vector * size distribution is a size distribution, the output of
ℕ = map(k -> T(zˢ,k,Λ,δ)*𝕟ᶜⁿ,1:3)
is an array of size distributions.
For more information see Figure 2 in the Manuscript, check out Session 2 of the Tutorial and/or Notebook S4 in the Notebooks section.
Complete Distribution
If the DMA is stepped or scanned, the response function can be computed from the convolution Matrix 𝐀 and the known true size distribution. The operation matrix * size distribution is defined in the Operators section. Thus we can conveniently write 𝕣 = 𝐀 * 𝕟
to compute the response function.
δ = setupDMA(Λ, z₁, z₂, 60);
𝕟 = DMALognormalDistribution([[400, 30, 1.2],[500, 110, 1.7]], δ)
𝕣 = δ.𝐀 * 𝕟
Tandem DMAs
Humidified Tandem DMA
Single Composition
Dried, charge equilibrated particles are classified in DMA1. The flow is split to measure particle concentration with a condensation particle counter (CPC). The remaining flow is passed through a humidifier. Hygroscopic particles take up water and increase in diameter. The humidified size distribution is measured using the second DMA that is operated in scanning or stepping mode. Passage through a second bipolar charger (charge neutralizer) is optional and rarely used in TDMA experiments.
To model transmission through the tandem DMA we need to
- setup two DMAs, δ₁ and δ₂
- know the input size distribution
- formulate a transmission model
Setting up DMAs is described in DMA Configuration. The input size distribution is assumed based on a lognormal distribution. The constructor function DMALognormalDistribution initializes a lognormal distribution along a DMA grid.
Ax = [[1300.0, 60.0, 1.4], [2000.0, 200.0, 1.6]]
𝕟ᶜⁿ = DMALognormalDistribution(Ax, δ₁)
The transmission model is a combination of operating DMA₁ at Constant Voltage and transmission of a Complete Distribution through DMA₂.
# Tandem DMA equations
O(k) = mapfoldl(zs -> (δ₂.Ω(Λ₂, δ₂.Z, zs / k, k) .* δ₂.Tl(Λ₂, δ₂.Z, k))', vcat, δ₂.Z)
T₁(zˢ, k) = δ₁.Ω(Λ₁, δ₁.Z, zˢ / k, k) .* δ₁.Tc(k, δ₁.Dp) .* δ₁.Tl(Λ₁, δ₁.Dp)
DMA₁(𝕟, zˢ, gf) = @_ map((gf ⋅ (T₁(zˢ, _) * 𝕟)), 1:6)
itp(𝕟) = interpolateSizeDistributionOntoδ((𝕟, δ₂))
DMA₂(𝕟, k) = O(k) * 𝕟
The function T(zˢ, k, Λ, δ)
is already known. The function DMA₁(𝕟, zˢ, gf)
takes a distribution 𝕟 and mobility zˢ and passes it through DMA Λ₁, δ₁ and applied growth factor gf. The resulting distributions are interpolated into the same grid as DMA2 using interpolateSizeDistributionOntoδ. The function DMA₂(𝕟, δ)
takes an input size distribution 𝕟 and passes it through DMA₂. No neutralizer is used. Therefore the convolution O(k) is applied. Note that O(k) corresponds to Eq. (15) in Petters (2021).
The dot product of scalar ⋅ SizeDistribution shifts the size distribution in diameter space: Size Operators. Check out the Tutorial Session 1 and/or Notebook S3 in the Notebooks section for visualizations.
Here is an abriged example how to compute the grown output distributions from DMA2
Dd = 100e-9 # Dry diameter
zˢ = dtoz(Λ₁, Dd); # Mobility of 100 nm particle
gf = 1.6 # Growth factor
ℕ = DMA₁(𝕟ᶜⁿ, zˢ, gf) # Transmission through DMA1
𝕄 = map(k -> (@> itp(ℕ[k]) DMA₂(k)), 1:3) # Transmission through DMA2
𝕞ᵗ = sum(𝕄) # total response
𝕄[k] correspond to the +1, +2, +3 partial mobility response functions that would be measured after DMA2. The total is obtained by the sum of these distributions Below is the complete example, which produces the response function of the tandem DMA.
t, p = 295.15, 1e5 # Temperature [K], Pressure [Pa]
qsa, β = 1.66e-5, 1 / 5 # Qsample [m3 s-1], Sample-to-sheath ratio
r₁, r₂, l = 9.37e-3, 1.961e-2, 0.44369 # DMA geometry [m]
Λ₁ = DMAconfig(t, p, qsa, qsa / β, r₁, r₂, l, 0.0, :-, 3, :cylindrical) # Specify DMA1
Λ₂ = DMAconfig(t, p, qsa, qsa / β, r₁, r₂, l, 0.0, :-, 3, :cylindrical) # Specify DMA2
bins, z₁, z₂ = 512, dtoz(Λ₁, 500e-9), dtoz(Λ₁, 30e-9) # bins, upper, lower mobility limit
δ₁ = setupDMA(Λ₁, z₁, z₂, bins) # Compute matrices
δ₂ = setupDMA(Λ₂, z₁, z₂, bins) # Compute matrices
# Upstream Size Distribution
Ax = [[1300.0, 60.0, 1.4], [5000.0, 220.0, 1.6]]
𝕟ᶜⁿ = DMALognormalDistribution(Ax, δ₁)
# Tandem DMA equations
O(k) = mapfoldl(zs -> (δ₂.Ω(Λ₂, δ₂.Z, zs / k, k) .* δ₂.Tl(Λ₂, δ₂.Z, k))', vcat, δ₂.Z)
T₁(zˢ, k) = δ₁.Ω(Λ₁, δ₁.Z, zˢ / k, k) .* δ₁.Tc(k, δ₁.Dp) .* δ₁.Tl(Λ₁, δ₁.Dp)
DMA₁(𝕟, zˢ, gf) = @_ map((gf ⋅ (T₁(zˢ, _) * 𝕟)), 1:3)
itp(𝕟) = interpolateSizeDistributionOntoδ((𝕟, δ₂))
DMA₂(𝕟, k) = O(k) * 𝕟
Dd = 100e-9 # Dry diameter
zˢ = dtoz(Λ₁, Dd); # Mobility of 100 nm particle
gf = 1.6 # Growth factor
ℕ = DMA₁(𝕟ᶜⁿ, zˢ, gf) # Transmission through DMA1
𝕄 = map(k -> (@> itp(ℕ[k]) DMA₂(k)), 1:3) # Transmission through DMA2
𝕞ᵗ = sum(𝕄) # total response
The figure demonstrates the apparent shift toward smaller growth factors for multicharge particles. See Petters (2021) for more explanation. The complete example is reproduced as transmission3.jl
in the examples/
folder of the main repository.
Multiple Compositions
The above example can be extended to write a TDMA model that integrates over a pdf. This function can be obtained from TDMA1Dpdf, which is part of the package.
function TDMA1Dpdf(𝕟ᵢₙ, Λ₁ᵢₙ, Λ₂ᵢₙ, dma2rangeᵢₙ)
Λ₁, Λ₂, 𝕟1 = deepcopy(Λ₁ᵢₙ), deepcopy(Λ₂ᵢₙ), deepcopy(𝕟ᵢₙ)
r = deepcopy(dma2rangeᵢₙ)
Dd, gmin, gmax, n = r[1], r[2], r[3], r[4]
nDMA, Dmin, Dmax = length(𝕟1.Dp), minimum(𝕟1.Dp), maximum(𝕟1.Dp)
δ₁ = setupDMA(Λ₁, dtoz(Λ₁, Dmax * 1e-9), dtoz(Λ₁, Dmin * 1e-9), nDMA)
δ₂ = setupDMA(Λ₂, dtoz(Λ₂, gmax * Dd), dtoz(Λ₂, gmin * Dd), n)
𝕟 = interpolateSizeDistributionOntoδ((𝕟1, δ₁))
@memoize O(k) = (hcat(map(i -> δ₂.Ω(Λ₂, δ₂.Z, i/k, k) .* δ₂.Tl(Λ₂, δ₂.Dp), δ₂.Z)...))'
@memoize T₁(zˢ, k) = δ₁.Ω(Λ₁, δ₁.Z, zˢ / k, k) .* δ₁.Tc(k, δ₁.Dp) .* δ₁.Tl(Λ₁, δ₁.Dp)
@memoize DMA₁(𝕟, zˢ, gf) = @_ map((gf ⋅ (T₁(zˢ, _) * 𝕟)), 1:6)
@memoize DMA₂(𝕟, k) = O(k) * 𝕟
@memoize itp(𝕟) = interpolateSizeDistributionOntoδ((𝕟, δ₂))
@memoize function TDMA(𝕟, zˢ, gf)
ℕ = DMA₁(𝕟, zˢ, gf)
map(k -> (@> itp(ℕ[k]) DMA₂(k)), 1:length(ℕ)) |> sum
end
@memoize model(𝕟, P, Dd, gf) =
sum(@_ map(P[_] * TDMA(𝕟, dtoz(Λ₁, Dd), gf[_]), 1:length(P)))
end
Note that the basic principle is the same as the single composition above. However, DMA₁(𝕟, zˢ, gf)
sums directly over all charges, so the individual charge distributions are not considered. The function TDMA(𝕟, zˢ, gf)
returns the output from the TDMA. The function model(𝕟, P, Dd, gf)
extends this over a pdf, where gf is a list of growth fractors and P are corresponding probabilities. It one possible implementation of Eqs. (16) and (17) in Petters (2021)
Below is an example with 4 population each having a unique growth factor and fractional contribution to the total distribution. If the fractions are known, the net response function of the TDMA is readily computed. The example is reproduced as transmission4.jl
in the examples folder of the main repository.
t, p = 295.15, 1e5
qsa, qsh = 1.66e-5, 8.33e-5
r₁, r₂, l = 9.37e-3, 1.961e-2, 0.44369
Λ₁ = DMAconfig(t, p, qsa, qsh, r₁, r₂, l, 0.0, :-, 6, :cylindrical)
Λ₂ = DMAconfig(t, p, qsa, qsh, r₁, r₂, l, 0.0, :-, 6, :cylindrical)
bins, z₁, z₂ = 120, dtoz(Λ₁, 500e-9), dtoz(Λ₁, 30e-9) # bins, upper, lower mobility limit
δ₁ = setupDMA(Λ₁, z₁, z₂, bins)
Ax = [[1300.0, 60.0, 1.4], [5000.0, 220.0, 1.6]]
𝕟 = DMALognormalDistribution(Ax, δ₁)
# scan 100 nm Dd from 0.8Dd to 3.0Dd with 100 bins
dma2range = (100e-9, 0.8, 3.0, 120)
# Get the model function
model = TDMA1Dpdf(𝕟, Λ₁, Λ₂, dma2range)
P = [0.5,0.15, 0.10, 0.25] # Probability of growth factor (4 populations)
gf = [1.0, 1.2, 1.6, 2.1] # Values of growth factor
𝕘 = model(𝕟, P, dma2range[1], gf)
Volatilty Tandem DMA
See the Manuscript and notebook S9 in the Notebooks section for examples involving the volatility tandem DMA.
Dual Tandem DMA
See the Manuscript and notebook S10 and S11 in the Notebooks section for examples involving the volatility tandem DMA.