File Exchange

image thumbnail


version (6.21 KB) by Harold Bien
Gaussian Plume model of airborne particulate distribution


Updated 05 Jan 2009

No License

gaussianPlume Steady-state 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 3-dimensional matrix containing the concentrations of the emitted
substance over a field with the first dimension (y) representing the
cross-wind 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 steady-state 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
Guifford-Pasquiill 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 Guifford-Pasquill 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
{'stack_pres', Ps} Sets stack tip pressure in millibars. Default is
{'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
'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 y-axis (cross-wind)
{'Z', z} Same as above except for the vertical axis

C=gaussianPlume(500, 5, 50, 'h_ref', 10, 'noreflection', ...
'nodeposition', 'amb_pres', 1103, 'amb_temp', 22);
Computes the steady-state Gaussian-distribution 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.

Comments and Ratings (14)

Hi. Can I know how to generate this code? I'm a new user of Matlab. Thank you.

Luis Lo

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,


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

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 Carlson-Moses 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 Short-Term (ISC3ST) model.


Thanks Harold - that helped a lot.

One more thing, I may be wrong, but here -
case 'Briggs'
% Compute buoyancy and momentum factors

Shouldn't temps be converted to Kelvin for the Briggs equations? From what I can gather input temps were in degrees C.


Harold Bien

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

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.


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!


Cesar Marcelo

Sam Duris

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.

Kostas Philippopoulos

Thank you for an excelent and detailed work!!!!!
It helped me a lot with a study that I am working on!

Harold Bien

Sorry, but this model only returns the "steady-state Gaussian distribution" so time is not an element - this is, in theory, at infinite time.

Kelvin Schleif

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?


Lisa - you're right. With the exception of Carlson-Moses 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'.

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.

Thanks to Colin Ritter at Humboldt State University who pointed out an error in the calculation for stable, buoyancy dominated Briggs plume rise, the denominator should have been surrounded in parenthesis, i.e. Fb/(us*s) rather than "Fb/us*s".

MATLAB Release Compatibility
Created with R14SP2
Compatible with any release
Platform Compatibility
Windows macOS Linux