Gaussian Plume model of airborne particulate distribution
26 Downloads
Updated 05 Jan 2009
No LicensegaussianPlume Steadystate gaussian plume distribution model
gaussianPlume models the dispersion of a continuous point source, i.e.
plume, in various conditions and terrains. The output of gaussianPlume
is a 3dimensional matrix containing the concentrations of the emitted
substance over a field with the first dimension (y) representing the
crosswind axis, the second dimension (x) the downwind distance, and
the third dimension (z) the vertical axis. The origin is set at the base
of the stack. All units are in <mgs> (meters, grams, seconds) except
where noted.
C = gaussianPlume(Q) returns the steadystate Gaussian distribution
model of a single, continuous point source emitting at a rate of Q
grams per second for a 50m physical stack height with no calculations
for plume rise, in rural terrain with stability class "F" in the
GuiffordPasquiill scale. Wind speed is assumed to be 1m/s at the stack
tip (50m).
C = gaussianPlume(Q, u_ref) sets the wind at 1m to be u_ref
C = gaussianPlume(Q, u_ref, h) sets the stack height to h
[C, z0] = gaussianPlume(...) returns the effective stack height in
meters as z0.
C = gaussianPlume(Q, u_ref, h, ...) allows you to set certain options.
Options are set by 'option', <option value> pairs except for certain
options which require no <option value>. The list of permissible
options are listed below:
{'h_ref', h_ref} Sets the reference height for the wind speed u_ref
in meters. Default is 1m.
{'stability', 'class'} Sets GuiffordPasquill stability class to
class 'class'. 'class' must be one of 'A', 'B', 'C', 'D', 'E',
or 'F'. Default is 'F'.
{'terrain', 't_type'} Sets the terrain to one of 'rural' or
'urban'. Default is 'urban'
{'p', p} Sets the scaling factor for change in wind as a
function of altitude to p. Default is 0.4.
{'plum_rise_model', 'model'} Sets the model to use for calculation
of plume rise. 'model' is one of 'none', 'CONCAWE',
'CarlsonMoses', 'Holland', or 'Briggs'. Default is 'none'.
{'mw', mw} Sets the molecular weight of the exhaust for plume rise
calculations. Specify in atomic mass units. Default is average
of air, 30g/mole.
{'amb_temp', Ta} Sets the ambient temperature in degrees Celsius.
Default is 25C.
{'stack_temp', Ts} Sets the stack temperature in degrees Celsius.
Default is 200C.
{'stack_diameter', ds} Sets the stack diameter (in meters). Default
is 20m.
{'specific_heat', Cp} Sets the specific heat of the exhaust gas in
J/degree Celsius/g. Default is 1.020 (constant pressure Cp for
dry air)
{'amb_pres', Pa} Sets ambient pressure in millibars. Default is
1010mb.
{'stack_pres', Ps} Sets stack tip pressure in millibars. Default is
1010mb.
{'vs', vs} Sets stack exit velocity in m/s. Default is 1m/s.
{'eta', eta} Sets the lapse rate for stable conditions (class E or
F).
'reflection' enables ground reflection (no option value)
'noreflection' disables ground reflection (no option value)
'deposition' models dry deposition (no option value)
'nodeposition' disables dry deposition (no option value)
{'vt', vt} Sets terminal/settling velocity in m/s. Default is
settling velocity for PM2.5, 0.5cm/s.
{'X', x} Sets sampling points at the downwind distances. x is a
vector specifying the downwind distances to evaluate for C in
meters. Default is 0 to 5km in 100m resolution.
{'Y', y} Same as above except for the yaxis (crosswind)
{'Z', z} Same as above except for the vertical axis
Example

C=gaussianPlume(500, 5, 50, 'h_ref', 10, 'noreflection', ...
'nodeposition', 'amb_pres', 1103, 'amb_temp', 22);
Computes the steadystate Gaussiandistribution of an emission at a
rate of 500g/s with average wind speed of 5m/s at 10m from a
physical stack height of 50m. No plume rise, reflection, nor
deposition will be modeled. The data will be sampled in 100m
resolution across the downwind and crosswind axes from 0 to 5km and
0 to 1km in the vertical axis.
1.2  Lisa  you're right. With the exception of CarlsonMoses and CONCAWE plume rise, I reviewed all equations and performed unit analysis. All temperatures now in Kelvins but input still in Celsius; fixed skipped entry in sigma_z for class 'E'. 

1.1  Thanks to Sam Duris who pointed out incorrect units were used in calculating sigma_z for rural and sigma_y for urban. I have also added in the documentation reference to the ISC3 User's Manual, Volume II, as the source for the equations. 
Sebastian Haug (view profile)
Dear Harold Bien,
Thank you for providing such an efficient dispersion program. You have done a good job with coding and documentation. I want to remind you that the Gaussian plume model is only valid for constant wind conditions in time and space. So the mean wind speed in the model area is U(x,y,z,t) = constant [Arya, S. P. – Air Pollution Meteorology and Dispersion,Oxford University Press, New York 199 (page 198 eq. 9.1)]. In your code line 468 ( u_matrix=((z_grid./h_ref).^p).*u_ref; ) you provide a logarithmic wind profile. That is wrong. The isosurfaces of a concentration contour in the x, y  direction do not show the typical characteristic of plume.
In a correct code u_matrix(:,:,:) = us; .
Best regards,
Sebastian
Lisa (view profile)
Harold, your code has been such a help. Another question, have you considered a variable for mixing depth? Putting in the option of reflection off an elevated inversion layer? Cheers, Lisa
Harold Bien (view profile)
They don't give much room to describe the updates, and then hide them at the bottom. In any case, Lisa, you were right  almost all the temps should be in Kelvins so I converted them for calculations but left the input in Celsius for convenience. Thanks for pointing that out. I have since reviewed all the equations (with the exception of CarlsonMoses and CONCAWE plume rise) and confirmed unit analysis where possible (many equations had constants with unknown units). Later when I get more time I plan to try to verify with supplied datasets for the ISC3 ShortTerm (ISC3ST) model.
Lisa (view profile)
Thanks Harold  that helped a lot.
One more thing, I may be wrong, but here 
case 'Briggs'
% Compute buoyancy and momentum factors
Fb=gc*vs*ds^2*(TsTa)/(4*Ts);
Fm=vs^2*ds^2*Ta/(4*Ts);
Shouldn't temps be converted to Kelvin for the Briggs equations? From what I can gather input temps were in degrees C.
Cheers,
Lisa
Harold Bien (view profile)
Hi Lisa,
In general, you are asking to perform volume visualization. MATLAB provides several options for what you are asking  if you search "Volume visualization" in MATLAB help you will find an extensive resource detailing how to do it. The 'C' variable that is returned is similar to the "scalar" volume data used in the examples given where C is a 3 dimensional matrix with a value for concentration at each point. In general, what you are attempting to do is difficult on a computer screen as the outside colors will obscure the interior data points. Methods around this limitation include transparency or taking "slices" from the volume. Again, the standard MATLAB help includes many functions that will help you to do this. Good luck.
Harold Bien (view profile)
Hi Sam Duris. This code was originally submitted as a homework assignment, and I regret if any errors have slipped in. Alas, I do not have a "standard text" available that display the proper results for the sigma_z curves, and would appreciate if you could point out where on the Internet I might be able to obtain for comparison/validation. Further, if you would be so kind as to list the specific problems/errors you encountered, I will be happy to try to address them. I have since located the two errors you point out where I inadvertently mixed km and m in computing sigma_z for rural and sigma_y for urban. I have also updated the documentation to note that most of the equations were actually taken from the ISC3 User's Manual, Vol II. It should be noted that this software is rather outdated, the EPA preferring AEROMOD/CALPUFF instead. Also, many of these models can be downloaded for free I think as well. I should note that many of these options have not been tested by me for accuracy. The division by zero errors likely come from passing 0 as a distance for evaluation and this will likely generate errors for which there is no real good solution other than having the user avoid calculations at 0 distance. The "documentation errors" to which you refer are too vague for me to locate  please clarify. Thanks for bringing up these errors and I look forward to improving this code.
Lisa (view profile)
I should be a little more clear  I want to plot the plume in 3d using the x,y,z and concentration data. I was wondering if anyone had written anything that would plot the 3d matrix with colours for concentration. I think I should be using the surf(x,y,z,c) plotting tool but I spent about three hours trying to work out what I am supposed to input for x,y,z ... I assume 'c' is the 3d concentration matrix? I am really revealing my cluelessness here  but this so isn't intuitive to me!
Ta.
Aside from numerious minor errors, e.g., needless divide by zero and incorrect documentation, the math is fundimentally incorrect for both rural and urban cases. Where kilometers should be used in the equations for rural plume dispersion meters are used and where meters should be used for the urban plume dispersion kilometers should be used. The equations were taken from standard text that have graphs displaying the correct sigma_z curves, which are not reproduced here. Apparently previous reviewers have little interest in testing the code they download.
Thank you for an excelent and detailed work!!!!!
It helped me a lot with a study that I am working on!
Sorry, but this model only returns the "steadystate Gaussian distribution" so time is not an element  this is, in theory, at infinite time.
I like the model, however the time element is not obvious to me.
How can I calculate the Plume's densities at different points in time?