Available languages: Matlab, Python, Javscript
The attached code evaluates the transfer function of particle mass analyzers (PMAs), including the centrifugal particle mass analyzer (CPMA) and aerosol particle mass analyzer (APM), in multiple languages, including Python and Javascript (used to build a web app). This is primarily done using a novel set of expressions derived from particle tracking methods, information for which is given in an associated paper (Sipkens, Olfert, and Rogak, 2020a). Further information on the different methods in this program is given as header information for each function.
This repository includes mat-tfer-pma as a submodule, which incorporates a Matlab version from a separate repository. More information is available in the README in that repository. What follows mostly pertains to the Python version available in this code.
The Matlab version is included as a submodule in the matlab folder, with the original code located in the mat-tfer-pma repository. We refer the reader to the README associated with that repository for more details, both on the Matlab specific implementation and general details about the transfer functions.
The Python version is in the py folder. This program require numpy; scipy; and generally relies on matplotlib for plotting. Full function requires that these packages be installed.
NOTE: This demonstration is also included as a Jupyter Notebook at main.ipynb. Only very minor differences exist between that implementation and the one presented below (e.g. outputting the setpoint dictionary using the json package).
To start, import the numpy library and, since we will be plotting data, the matplotlib.pyplot module,
import matplotlib.pyplot as plt
import numpy as np
Also, import the tfer_pma module, which contains the relevant functions to evaluate the transfer function using the analytical methods from Sipkens, Olfert, and Rogak (2020a), and prop_pma, which is used to load the relevant PMA properties (e.g., classifier length, flow rate):
from prop_pma import prop_pma # import method to load PMA properties
import tfer_pma # import PMA transfer function methods
Now define some fundamental properties, including the mass setpoint, m_star
; the masses at which to evaluate the transfer function, m
; the mobility diameter of the particles, d
(note, using d = None
will result in using the mass-mobility relation, using the values in the prop
dictionary defined below); and the integer charge state at which to evaluate the transfer function, z
:
# define input variables
m_star = 0.01e-18
# numpy array spanning 80 to 120% m_star
m = np.arange(0.8,1.2,0.001) * m_star
d = None # mobility diameter
z = 1. # integer charge state
Next, generate a dictionary that contains the properties of the particle mass analyzer, such as its geometry dimensions. Here, we also modify the default mass-mobility parameters to be used in the remainder of the program:
prop = prop_pma() # get default PMA properties
# Modify some of the properties,
# in this case for the mass-mobility relation.
rho_eff = 900; # effective density
prop['m0'] = rho_eff * np.pi / 6 * 1e-27 # only used to find Rm
prop['Dm'] = 3
The default parameters here correspond to a centrifugal particle mass analyzer (CPMA), where the electrodes rotate at different speed. We could return an aerosol particle mass analyzer (APM) by setting the ratio of electrode speeds to unity, using:
prop['omega_hat'] = 1; # ratio of angular speeds (CPMA < 1 vs APM = 1)
Now we generate a setpoint dictionary. This quantity is crucial in this program, taking the prop
dictionary generated above and two name-value pair arguments that specify the setpoint for the PMA. For example, using the mass setpoint m_star
above and a resolution (as defined by Reavell, Symonds, and Rushton (2011)) of 10, we can compute the other relevant parameters to describe the PMA setpoint using:
sp,_ = tfer_pma.get_setpoint(prop, 'm_star', m_star, 'Rm', 10)
The output dictionary will also contain information like the voltage, sp['V']
; angular speeds of the inner and outer electrodes, sp['omega1']
and sp['omega2']
, respectively; among other relevant properties. One can also use other pairings, such as specifying the voltage and centerline rotation speed:
sp,_ = tfer_pma.get_setpoint(prop, 'V', 24.44, 'omega', 2543.9)
This should give a similar setpoint to the preceding statement, but specifies the setpoint in a different way. It is worth noting that most combinations of two of these parameters will be sufficient to specify to setpoint, with the exception of combining the rotational speed or voltage with a resolution, which will result in an error.
Finally, let's evaluate the transfer function for some of the cases considered in Sipkens, Olfert, and Rogak (2020a). First, consider Case 1S, where the fluid velocity profile is approximated using a 1st-order Taylor series expansion about the equilibrium radius. To do so:
Lambda_1S,_ = tfer_pma.tfer_1S(sp, m, d, z, prop)
Here, Lambda_1S
will be a numpy array of the same length as m
. The other expressions from Sipkens, Olfert, and Rogak (2020a) can be realized using different methods from tfer_pma module, generally adopting intuitive names corresponding to the case codes from that work. For example, for Case 1C:
Lambda_1C,_ = tfer_pma.tfer_1C(sp, m, d, z, prop)
Adding diffusion to this scenario can be done by adding _diff
to the end of the method name above:
Lambda_1C_diff,_ = tfer_pma.tfer_1C_diff(sp, m, d, z, prop)
To finish, plot the evaluate transfer functions,, with the result resembling some of the plots in Sipkens, Olfert, and Rogak (2020a):
# plot the various transfer functions
plt.plot(m, Lambda_1S)
plt.plot(m, Lambda_1C)
plt.plot(m, Lambda_1C_diff)
plt.show()
This sample code is given in the main.py script that is provided with this program.
A Javascript version is available in the js folder, with dependencies on the math.js and optimization.js packages. That code is structured similarly to the other versions described below.
This version supports a web app available at https://tsipkens.github.io/tfer-pma, which allows the user to interact with basic versions of the transfer function. The corresponding Javascript file responsible for the plotting is available in the docs folder.
This software is licensed under an MIT license (see the corresponding file or details).
This program was written by Timothy A. Sipkens (tsipkens@mail.ubc.ca) while at the University of British Columbia. This program was written in close association with Steven Rogak (University of British Columbia) and Jason Olfert (University of Alberta).
This code should be cited by:
-
citing the associated journal article describing the particle tracking methods used in this program (Sipkens, Olfert, and Rogak, 2020a), and
-
optionally citing the code directly (making reference to the GitHub repository at https://github.com/tsipkens/tfer-pma).