Introduction to aerosolpy¶
Purpose¶
aerosolpy is a collection of functions and classes which developed over
the years since my PhD in aerosol physics with all kinds of utilities which
facilitate calculations related to aerosol physics and chemistry.
aerosolpy is not a package which serves a single puropse and by no means
a compelete software tool which aims to provide everything to the user.
It is really a collection of different things. There might be evry important
functions missing and some functions might seem useless to another user.
However, as it is structured currently it provides a python package which is useful especially for calculating basic mechanics and kinetics operations, provides classes which describe typical aerosol sizing instruments, and will be extended to also include data inversion software for mobility particle size spectrometers and a simulation package which facilitates aerosol growth calculations.
Disclaimer¶
I will not be liable for potential errors in these calculations.
It is actually highly likely that there might be some mistakes. Please be
careful when using aerosolpy.
Basics¶
Once installed import aerosolpy as follows, using the recommended abbreviation ap:
import aerosolpy as ap
There are serval base functions provided within aerosolpy which include typical unit conversions, time format conversions and math operations. They can be accessed within the ap namespace:
ap.lpm_to_m3pers(1.5)
This for example converst the typical air flow unit litre per minute to SI units, i.e. cubic meter per second.
Another operation which was often needed when analyzing data with different
software was the conversion of time stamps, especially going from the widely
used MATLAB to python:
ap.matlab2datetime(matlab_timestamp)
Whenever the need for a new basic function will appear in my future work I will
update them in aerosolpy.
AerosolMechanics and AerosolKinetics¶
Two major classes included in the basic aerosolpy package are
ap.AerosolMechanics and ap.AerosolKinetics.
AerosolMechanics was designed to provide calculations related to the
motion of aerosol particles and vapor molecules within air. It is designed
as a class, that means for accessing its methods (the necessary calculations)
we need to create an instance of that class, an AerosolMechanics object:
amech = ap.AerosolMechanics(temp_kelvin=273.15, press_hpa=1013)
The object defines all physics parameters of air at the given temperature and
pressure. It for example calculates the mean free path of air molecules and the
dynamic viscosity of air directly. Temperature and pressure of a given
ap.AerosolMechanics object can be changed during program execution, e.g.:
amech.set_temp(293.15)
AerosolKinetics was designed to provide kinetic calculations in the sense
of chemical kinetics, i.e. collision frequencies between aerosols and aerosols
and vapor molecules. As with AerosolMechanics it is implemented as class,
which inherits from ap.AerosolMechanics, i.e. an object of AerosolKinetics
also includes the methods from AerosolMechanics:
akin = ap.AerosolKinetics(temp_kelvin=273.15)
akin.set_temp(293.15)
Its main purpose however is to provide additional functions such as the coagulation kernel of two aerosol particles:
akin.coll_kernel_pp(10.0,100.0)
Subpackage: aerosolpy.instr¶
The aerosolpy.instr package provides additional classes which define
objects related to typical aerosol measurement devices, currently implemented
is a differential mobility analyzer (DMA; ap.instr.Dma and its subclass
ap.instr.DmaCylindrical), a condensation particle counter (CPC;
ap.instr.Cpc) and a mobility particle size spectrometer
(MPSS; ap.instr.Mpss). Here the object-orientated programming
style of aerosolpy might be slightly more intuitive.
An instance of the ap.instr.DmaCylindrical class just represents a
cylindrical DMA with its geometry (radii of the cylinders, length of the
aerosol extraction pathways), flow conditions (aerosol sample and sheath flows)
and other parameters. It the provides methods to e.g. convert voltages applied
to the central electrode to diameters classified assuming a certain charge on
the particles:
cy_dma = ap.instr.DmaCylindrical(q_a=1.5, q_sh=7.5, length=0.109,
r_i=0.025, r_o=0.033)
cy_dma.v_to_dp(1000)
In a similar manner we can define CPCs using ap.instr.Cpc class with e.g.
predefined activation curves:
tsi3772_cpc = ap.instr.Cpc(activation='tsi_3772_ag')
Mobility Particle Size Spectrometers build upon these two classes as every MPSS typically consists of a DMA for particle size classification and a CPC for particle detection (concentration measurement):
channel_sizes = np.array([10.,20.,30.,50.,100.])
custom_mpss = ap.instr.Mpss(channel_sizes, cy_dma, cpc=tsi3772_cpc)
It then contains methods which can invert MPSS data:
raw_conc_per_channel = np.array([2, 7.2, 8.9, 3., 0.])
nsd = custom_mpss.std_inv(raw_conc_per_channel, imax=5)
where nsd is then the inverted size distribution taking into account
multiple charges on aerosol particles up to imax=5.
Subpackage: aerosolpy.growth¶
The aerosolpy.growth package provides additional classes for theoretical
calculations of particle growth rates from vapor concentrations.
The class ap.growth.KineticLimit provides a calculus for growth rates of
vapors which condense purely kinetically, i.e. there is no evaporation of
the vapor back into the gas-phase, but based only on vapor properties such
as molecular mass and density:
kg = ap.growth.KineticLimit(98, 1830)
gr = kg.growth_rate(5.0, 2e7, kernel='hard sphere')
Particle size at which the growth rate is calculated (in nm) and condensing
vapor concentration are defined in the ap.growth.KineticLimit.growth_rate
method. Optional is the usage of a collision frequency kernel which e.g.
includes collision enhancement due to van der Waals interactions
The class ap.growth.SulfuricAcid() is based on the same assumption that
sulfuric acid condenses at the kinetic limit, but includes a treatement of
co-condensing water and more precise knowledge on sulfuric acid properties, but
the basic principle is identical:
sa = ap.growth.SulfuricAcid(temp_kelvin=278.15)
gr = sa.growth_rate(5.0, 1e7, hamaker=5.2e-20,
kernel='sceats', hydration='dry measurement'
)
We see that there are more optional arguments, i.e. specifiying the assumed hydration of the vapor molecules and particles during growth rate measurement. The calculus of this class follows Stolzenburg et al. (2020), Atmos. Chem. Phys.
The class ap.growth.VbsModel() is used to calculate the condensation of
organics with different volatility. It relies on the volatility-basis-set
which groups together organic molecules of similar volatility (vapor pressure).
The input for the growth model is more complex compared to the other clases, as
the model calculates a numerical solution to the growth problem (and not an
analytical solution as the other two classes). The model first needs to be set-
up with the input:
vbs = ap.growth.VbsModel(0, conc, mass, logc)
where conc, mass, logc are each a np.array containing the
gas-phase concentrations of the VBS-bins (here 1D, but time evolution is
possible as well if the first argument of the model is a time-step np.array
), the average moelcular masses of the VBS-bins, and the saturation vapor
pressure of the bins (in terms of logarithmic saturation mass concentration).
After model-setup, it can be run with the ap.growth.VbsModel.calc_vbs_dynamics
method:
dp, gr, bins, t = vbs.calc_vbs_dynamics()
This outputs the entire dp versus gr trajectory of the growing
particles, together with the growth rate per bin (bins). If only the
growth rate at a specific diameter is of interest, the syntax is the same as
with the other classes:
gr = vbs.growth_rate(5.0)
The class ap.growth.VbsModel additionally contains more complex versions
of the growth model, which also include co-condensation of sulfuric acid,
dynamically calculated activity coefficients and simnple particle-phase
reaction schemes. Details can be found in the index.