Path: blob/main/latex-templates/templates/atmospheric-science/air_pollution.tex
51 views
unlisted
\documentclass[11pt,a4paper]{article}1\usepackage[utf8]{inputenc}2\usepackage[T1]{fontenc}3\usepackage{amsmath,amssymb}4\usepackage{graphicx}5\usepackage{booktabs}6\usepackage{siunitx}7\usepackage{geometry}8\geometry{margin=1in}9\usepackage{pythontex}10\usepackage{hyperref}11\usepackage{float}1213\title{Air Pollution Dispersion\\Gaussian Plume Modeling}14\author{Environmental Engineering Department}15\date{\today}1617\begin{document}18\maketitle1920\begin{abstract}21Computational analysis of air pollution dispersion using Gaussian plume models and deposition calculations.22\end{abstract}232425\section{Introduction}2627Air pollution dispersion models predict pollutant concentrations downwind of emission sources.2829\begin{pycode}30import numpy as np31import matplotlib.pyplot as plt32plt.rcParams['text.usetex'] = True33plt.rcParams['font.family'] = 'serif'34\end{pycode}3536\section{Gaussian Plume Model}3738$C(x,y,z) = \frac{Q}{2\pi u \sigma_y \sigma_z} \exp\left(-\frac{y^2}{2\sigma_y^2}\right) \left[\exp\left(-\frac{(z-H)^2}{2\sigma_z^2}\right) + \exp\left(-\frac{(z+H)^2}{2\sigma_z^2}\right)\right]$3940\begin{pycode}41def gaussian_plume(x, y, z, Q, u, H, stability='D'):42# Pasquill-Gifford dispersion parameters43if stability == 'A':44a_y, b_y, a_z, b_z = 0.22, 0.894, 0.20, 1.045elif stability == 'D':46a_y, b_y, a_z, b_z = 0.08, 0.894, 0.06, 0.91147elif stability == 'F':48a_y, b_y, a_z, b_z = 0.04, 0.894, 0.016, 0.754950sigma_y = a_y * x**b_y51sigma_z = a_z * x**b_z5253C = Q / (2 * np.pi * u * sigma_y * sigma_z) * \54np.exp(-y**2 / (2 * sigma_y**2)) * \55(np.exp(-(z - H)**2 / (2 * sigma_z**2)) + np.exp(-(z + H)**2 / (2 * sigma_z**2)))56return C5758# Parameters59Q = 100 # g/s emission rate60u = 5 # m/s wind speed61H = 50 # m stack height6263x = np.linspace(100, 5000, 200)64C_ground = gaussian_plume(x, 0, 0, Q, u, H)6566fig, ax = plt.subplots(figsize=(10, 6))67ax.semilogy(x/1000, C_ground * 1e6, 'b-', linewidth=2)68ax.set_xlabel('Downwind Distance (km)')69ax.set_ylabel('Concentration ($\\mu$g/m$^3$)')70ax.set_title('Ground-Level Concentration')71ax.grid(True, alpha=0.3, which='both')72plt.tight_layout()73plt.savefig('plume_centerline.pdf', dpi=150, bbox_inches='tight')74plt.close()75\end{pycode}7677\begin{figure}[H]78\centering79\includegraphics[width=0.85\textwidth]{plume_centerline.pdf}80\caption{Ground-level pollutant concentration along plume centerline.}81\end{figure}8283\section{Stability Class Effects}8485\begin{pycode}86fig, ax = plt.subplots(figsize=(10, 6))87for stab in ['A', 'D', 'F']:88C = gaussian_plume(x, 0, 0, Q, u, H, stability=stab)89ax.semilogy(x/1000, C * 1e6, linewidth=1.5, label=f'Class {stab}')90ax.set_xlabel('Downwind Distance (km)')91ax.set_ylabel('Concentration ($\\mu$g/m$^3$)')92ax.set_title('Effect of Atmospheric Stability')93ax.legend()94ax.grid(True, alpha=0.3, which='both')95plt.tight_layout()96plt.savefig('stability_effects.pdf', dpi=150, bbox_inches='tight')97plt.close()98\end{pycode}99100\begin{figure}[H]101\centering102\includegraphics[width=0.85\textwidth]{stability_effects.pdf}103\caption{Concentration for different stability classes.}104\end{figure}105106\section{2D Concentration Field}107108\begin{pycode}109x_2d = np.linspace(100, 3000, 100)110y_2d = np.linspace(-500, 500, 100)111X, Y = np.meshgrid(x_2d, y_2d)112C_2d = gaussian_plume(X, Y, 0, Q, u, H)113114fig, ax = plt.subplots(figsize=(12, 6))115cs = ax.contourf(X/1000, Y, C_2d * 1e6, levels=20, cmap='YlOrRd')116plt.colorbar(cs, label='Concentration ($\\mu$g/m$^3$)')117ax.set_xlabel('Downwind Distance (km)')118ax.set_ylabel('Crosswind Distance (m)')119ax.set_title('Ground-Level Concentration Field')120plt.tight_layout()121plt.savefig('concentration_field.pdf', dpi=150, bbox_inches='tight')122plt.close()123\end{pycode}124125\begin{figure}[H]126\centering127\includegraphics[width=0.95\textwidth]{concentration_field.pdf}128\caption{2D ground-level concentration contours.}129\end{figure}130131\section{Stack Height Effects}132133\begin{pycode}134heights = [30, 50, 100, 150]135136fig, ax = plt.subplots(figsize=(10, 6))137for H_s in heights:138C = gaussian_plume(x, 0, 0, Q, u, H_s)139ax.semilogy(x/1000, C * 1e6, linewidth=1.5, label=f'H = {H_s} m')140ax.set_xlabel('Downwind Distance (km)')141ax.set_ylabel('Concentration ($\\mu$g/m$^3$)')142ax.set_title('Effect of Stack Height')143ax.legend()144ax.grid(True, alpha=0.3, which='both')145plt.tight_layout()146plt.savefig('stack_height_effects.pdf', dpi=150, bbox_inches='tight')147plt.close()148\end{pycode}149150\begin{figure}[H]151\centering152\includegraphics[width=0.85\textwidth]{stack_height_effects.pdf}153\caption{Ground concentration for different stack heights.}154\end{figure}155156\section{Maximum Concentration}157158\begin{pycode}159x_max = H * np.sqrt(2) # Approximate location of max160C_max = gaussian_plume(x, 0, 0, Q, u, H)161idx_max = np.argmax(C_max)162163fig, ax = plt.subplots(figsize=(10, 6))164ax.plot(x/1000, C_max * 1e6, 'b-', linewidth=2)165ax.plot(x[idx_max]/1000, C_max[idx_max] * 1e6, 'ro', markersize=10)166ax.annotate(f'Max: {C_max[idx_max]*1e6:.1f} $\\mu$g/m$^3$\nat {x[idx_max]/1000:.1f} km',167xy=(x[idx_max]/1000, C_max[idx_max]*1e6), xytext=(x[idx_max]/1000 + 1, C_max[idx_max]*1e6 * 1.5),168arrowprops=dict(arrowstyle='->'))169ax.set_xlabel('Downwind Distance (km)')170ax.set_ylabel('Concentration ($\\mu$g/m$^3$)')171ax.set_title('Maximum Ground-Level Concentration')172ax.grid(True, alpha=0.3)173plt.tight_layout()174plt.savefig('maximum_concentration.pdf', dpi=150, bbox_inches='tight')175plt.close()176\end{pycode}177178\begin{figure}[H]179\centering180\includegraphics[width=0.85\textwidth]{maximum_concentration.pdf}181\caption{Location and magnitude of maximum concentration.}182\end{figure}183184\section{Vertical Profile}185186\begin{pycode}187z_profile = np.linspace(0, 200, 100)188x_loc = 1000 # m189190C_vertical = gaussian_plume(x_loc, 0, z_profile, Q, u, H)191192fig, ax = plt.subplots(figsize=(8, 8))193ax.plot(C_vertical * 1e6, z_profile, 'b-', linewidth=2)194ax.axhline(y=H, color='r', linestyle='--', label=f'Stack height = {H} m')195ax.set_xlabel('Concentration ($\\mu$g/m$^3$)')196ax.set_ylabel('Height (m)')197ax.set_title(f'Vertical Profile at x = {x_loc} m')198ax.legend()199ax.grid(True, alpha=0.3)200plt.tight_layout()201plt.savefig('vertical_profile.pdf', dpi=150, bbox_inches='tight')202plt.close()203\end{pycode}204205\begin{figure}[H]206\centering207\includegraphics[width=0.7\textwidth]{vertical_profile.pdf}208\caption{Vertical concentration profile.}209\end{figure}210211\section{Results}212213\begin{pycode}214x_max_dist = x[idx_max]215C_max_val = C_max[idx_max] * 1e6216217print(r'\begin{table}[H]')218print(r'\centering')219print(r'\caption{Dispersion Model Results}')220print(r'\begin{tabular}{@{}lc@{}}')221print(r'\toprule')222print(r'Parameter & Value \\')223print(r'\midrule')224print(f'Emission rate & {Q} g/s \\\\')225print(f'Wind speed & {u} m/s \\\\')226print(f'Stack height & {H} m \\\\')227print(f'Max concentration & {C_max_val:.1f} $\\mu$g/m$^3$ \\\\')228print(f'Distance to max & {x_max_dist:.0f} m \\\\')229print(r'\bottomrule')230print(r'\end{tabular}')231print(r'\end{table}')232\end{pycode}233234\section{Conclusions}235236Gaussian plume models provide practical estimates of pollutant dispersion for regulatory applications.237238239\end{document}240241242