{
"cells": [
{
"cell_type": "markdown",
"id": "7968866b-24b8-4ed6-bc13-6035310cb4f5",
"metadata": {},
"source": [
"[](https://github.com/open-atmos/PyPartMC/blob/main/examples/particle_simulation.ipynb) \n",
"[](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/particle_simulation.ipynb) \n",
"[](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/particle_simulation.ipynb) \n",
"[](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=) (requires [logging in with ARM account](https://www.arm.gov/capabilities/computing-resources) and directing Jupyter to a notebook within the cloned repo)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "159edeb4",
"metadata": {},
"outputs": [],
"source": [
"# This file is a part of PyPartMC licensed under the GNU General Public License v3\n",
"# Copyright (C) 2023 University of Illinois Urbana-Champaign\n",
"# Authors:\n",
"# - https://github.com/compdyn/partmc/graphs/contributors\n",
"# - https://github.com/open-atmos/PyPartMC/graphs/contributors"
]
},
{
"cell_type": "markdown",
"id": "22ddb300-38b5-437f-b264-9a5d2cc6e549",
"metadata": {},
"source": [
"### Urban plume simulation: based on Riemer et al. 2009 (JGR) \"Simulating the evolution of soot mixing state with a particle‐resolved aerosol model.\"\n",
"\n",
"https://doi.org/10.1029/2008JD011073\n",
"\n",
"This simulation shows the evolution of carbonaceous aerosols from different emission types\n",
"in an idealized urban plume case representative of a large urban area. This notebook also provides a\n",
"step-by-step description of how to set up and run other user-defined PyPartMC simulations."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "4f8359c2",
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"import os\n",
"if 'google.colab' in sys.modules:\n",
" !pip --quiet install open-atmos-jupyter-utils\n",
" from open_atmos_jupyter_utils import pip_install_on_colab\n",
" pip_install_on_colab('PyPartMC')\n",
"elif 'JUPYTER_IMAGE' in os.environ and '.arm.gov' in os.environ['JUPYTER_IMAGE']:\n",
" !pip --quiet install PyPartMC open_atmos_jupyter_utils\n",
" _pypartmc_path = !pip show PyPartMC | fgrep Location | cut -f2 -d' '\n",
" sys.path.extend(_pypartmc_path if _pypartmc_path[0] not in sys.path else [])"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "b494ea6e",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib\n",
"from open_atmos_jupyter_utils import show_plot\n",
"import PyPartMC as ppmc\n",
"from PyPartMC import si"
]
},
{
"cell_type": "markdown",
"id": "88eb4be5-9091-4588-a43f-f9936993b089",
"metadata": {},
"source": [
"#### Defining gas species (GasData)\n",
"\n",
"The ``ppmc.GasData`` object contains information regarding the tracked gas species.\n",
"Here an example `gas_data`is the set of gas species from the CBMZ gas-phase mechanism \n",
"as PartMC is often coupled to the Model for Simulating Aerosol Interactions and Chemistry (MOSAIC)\n",
"which uses the CBM-Z gas-phase mechanism such as was the case in Riemer et al. 2009."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "df8d1a84",
"metadata": {},
"outputs": [],
"source": [
"gas_data = ppmc.GasData((\"H2SO4\",\"HNO3\",\"HCl\",\"NH3\",\"NO\",\"NO2\", \"NO3\",\n",
" \"N2O5\", \"HONO\", \"HNO4\", \"O3\", \"O1D\", \"O3P\", \"OH\",\n",
" \"HO2\", \"H2O2\", \"CO\", \"SO2\", \"CH4\", \"C2H6\", \"CH3O2\", \n",
" \"ETHP\", \"HCHO\", \"CH3OH\", \"ANOL\", \"CH3OOH\", \"ETHOOH\",\n",
" \"ALD2\", \"HCOOH\", \"RCOOH\", \"C2O3\", \"PAN\", \"ARO1\", \"ARO2\",\n",
" \"ALK1\", \"OLE1\", \"API1\", \"API2\", \"LIM1\", \"LIM2\", \"PAR\", \"AONE\",\n",
" \"MGLY\", \"ETH\", \"OLET\", \"OLEI\", \"TOL\", \"XYL\", \"CRES\", \"TO2\",\n",
" \"CRO\", \"OPEN\", \"ONIT\", \"ROOH\", \"RO2\", \"ANO2\", \"NAP\", \"XO2\",\n",
" \"XPAR\", \"ISOP\", \"ISOPRD\", \"ISOPP\", \"ISOPN\", \"ISOPO2\", \"API\",\n",
" \"LIM\", \"DMS\", \"MSA\", \"DMSO\", \"DMSO2\", \"CH3SO2H\", \"CH3SCH2OO\", \n",
" \"CH3SO2\", \"CH3SO3\", \"CH3SO2OO\", \"CH3SO2CH2OO\", \"SULFHOX\"\n",
" ))"
]
},
{
"cell_type": "markdown",
"id": "c7397d69-eed0-4eb3-9a5f-ca3084a372e0",
"metadata": {},
"source": [
"#### Defining aerosol species and their properties (AeroData)\n",
"\n",
"The `ppmc.AeroData` object contains the set of tracked aerosol species and their physical\n",
"properties. Here `aero_data` contains 20 different aerosol species with their specified physical properties such as density, molecular weight and hygroscopicity parameter $\\kappa$."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "815283a0",
"metadata": {},
"outputs": [],
"source": [
"aero_data = ppmc.AeroData(\n",
" (\n",
" # density ions in soln (1) molecular weight kappa (1)\n",
" # | | | |\n",
" {\"SO4\": [1800 * si.kg / si.m**3, 0, 96.0 * si.g / si.mol, 0.65]},\n",
" {\"NO3\": [1800 * si.kg / si.m**3, 0, 62.0 * si.g / si.mol, 0.65]},\n",
" {\"Cl\": [2200 * si.kg / si.m**3, 0, 35.5 * si.g / si.mol, 1.28]},\n",
" {\"NH4\": [1800 * si.kg / si.m**3, 0, 18.0 * si.g / si.mol, 0.65]},\n",
" {\"MSA\": [1800 * si.kg / si.m**3, 0, 95.0 * si.g / si.mol, 0.53]},\n",
" {\"ARO1\": [1400 * si.kg / si.m**3, 0, 150.0 * si.g / si.mol, 0.10]},\n",
" {\"ARO2\": [1400 * si.kg / si.m**3, 0, 150.0 * si.g / si.mol, 0.10]},\n",
" {\"ALK1\": [1400 * si.kg / si.m**3, 0, 140.0 * si.g / si.mol, 0.10]},\n",
" {\"OLE1\": [1400 * si.kg / si.m**3, 0, 140.0 * si.g / si.mol, 0.10]},\n",
" {\"API1\": [1400 * si.kg / si.m**3, 0, 184.0 * si.g / si.mol, 0.10]},\n",
" {\"API2\": [1400 * si.kg / si.m**3, 0, 184.0 * si.g / si.mol, 0.10]},\n",
" {\"LIM1\": [1400 * si.kg / si.m**3, 0, 200.0 * si.g / si.mol, 0.10]},\n",
" {\"LIM2\": [1400 * si.kg / si.m**3, 0, 200.0 * si.g / si.mol, 0.10]},\n",
" {\"CO3\": [2600 * si.kg / si.m**3, 0, 60.0 * si.g / si.mol, 0.53]},\n",
" {\"Na\": [2200 * si.kg / si.m**3, 0, 23.0 * si.g / si.mol, 1.28]},\n",
" {\"Ca\": [2600 * si.kg / si.m**3, 0, 40.0 * si.g / si.mol, 0.53]},\n",
" {\"OIN\": [2600 * si.kg / si.m**3, 0, 1.0 * si.g / si.mol, 0.10]},\n",
" {\"OC\": [1400 * si.kg / si.m**3, 0, 1.0 * si.g / si.mol, 0.001]},\n",
" {\"BC\": [1800 * si.kg / si.m**3, 0, 1.0 * si.g / si.mol, 0.00]},\n",
" {\"H2O\": [1000 * si.kg / si.m**3, 0, 18.0 * si.g / si.mol, 0.00]},\n",
" )\n",
")"
]
},
{
"cell_type": "markdown",
"id": "bf7211e9-4111-4a11-90eb-7b06b0610986",
"metadata": {},
"source": [
"#### Initializing gas mixing ratios (GasState)\n",
"\n",
"The `ppmc.GasState` object tracks the current state of the gas mixing ratios (units: ppb).\n",
"The size and order of species in `gas_state` are defined by `gas_data`.\n",
"Here all non-zero gas species values in a tuple have be set to `gas_state.mix_rats`, which is the full list of gas mixing ratios. The initial condition of gases mixing ratios can be found in Table 1. "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "c822823d",
"metadata": {},
"outputs": [],
"source": [
"gas_state = ppmc.GasState(gas_data)\n",
"\n",
"gas_state.mix_rats = (\n",
" {\"NO\": [0.1E+00]},\n",
" {\"NO2\": [1.0E+00]},\n",
" {\"HNO3\": [1.0E+00]},\n",
" {\"O3\": [5.0E+01]},\n",
" {\"H2O2\": [1.1E+00]},\n",
" {\"CO\": [2.1E+02]},\n",
" {\"SO2\": [0.8E+00]},\n",
" {\"NH3\": [0.5E+00]},\n",
" {\"HCl\": [0.7E+00]},\n",
" {\"CH4\": [2.2E+03]},\n",
" {\"C2H6\": [1.0E+00]},\n",
" {\"HCHO\": [1.2E+00]},\n",
" {\"CH3OH\": [1.2E-01]},\n",
" {\"CH3OOH\": [0.5E+00]},\n",
" {\"ALD2\": [1.0E+00]},\n",
" {\"PAR\": [2.0E+00]},\n",
" {\"AONE\": [1.0E+00]},\n",
" {\"ETH\": [0.2E+00]},\n",
" {\"OLET\": [2.3E-02]},\n",
" {\"OLEI\": [3.1E-04]},\n",
" {\"TOL\": [0.1E+00]},\n",
" {\"XYL\": [0.1E+00]},\n",
" {\"ONIT\": [0.1E+00]},\n",
" {\"PAN\": [0.8E+00]},\n",
" {\"RCOOH\": [0.2E+00]},\n",
" {\"ROOH\": [2.5E-02]},\n",
" {\"ISOP\": [0.5E+00]}\n",
")"
]
},
{
"cell_type": "markdown",
"id": "4926ef36-37ef-4d02-9256-2220ca1f6230",
"metadata": {},
"source": [
"### Aerosol size distribution\n",
"\n",
"The initial, background, and emitted number distributions are superpositions of lognormal distributions, each defined by:\n",
"\n",
"$n(D) = \\frac{N}{\\sqrt{2 \\pi} \\log_{10} \\sigma_{\\rm g}} \\exp \n",
" \\left(- \\frac{\\left(\\log_{10} D - \\log_{10} D_{\\rm gn} \\right)^2}\n",
" {2 \\log_{10}^2 \\sigma_{\\rm g}}\\right)$,\n",
"\n",
"where $N$ is the total number concentration, $D_{\\rm gn}$ is the geometric mean diameter and $\\sigma_{\\rm g}$\n",
"is the geometric standard deviation.\n",
"\n",
"#### Initial aerosol distributions\n",
"\n",
"The initial aerosol distribution consists of two lognormal modes as follows (from Table 2)\n",
"\n",
"| Mode | $N$ (m$^{-3}$) | $D_{\\rm gn}$ ($\\micro$m) | $\\sigma_{\\rm g}$ | Composition|\n",
"|--------------|-------------------|--------------------------|------------------|------------|\n",
"| Aitken | $3.2 \\times 10^9$ | 0.02 | 1.45 | 50% (NH4)2SO4, 50% POA |\n",
"| Accumulation | $2.9 \\times 10^9$ | 0.116 | 1.65 | 50% (NH4)2SO4, 50% POA |\n",
"\n",
"#### Emitted aerosol distributions\n",
"\n",
"Emissions consist of three lognormal modes as follows (from Table 2)\n",
"\n",
"| Mode | $E$ (m$^{-2}$)| $D_{\\rm gn}$ ($\\micro$m) | $\\sigma_g$ | Composition |\n",
"|----------|----------|----------|----------|----------|\n",
"| Meat cooking | $3.2 \\times 10^9$ | 0.086 | 1.9 | 100% POA |\n",
"| Diesel vehicles | $2.9 \\times 10^9$ | 0.05 | 1.7 | 30% POA, 70% BC |\n",
"| Gasoline vehicles | $2.9 \\times 10^9$ | 0.05 | 1.7 | 80% POA, 20% BC |\n",
"\n",
"where $E$ is the area emission source strength. The emission process in PartMC takes\n",
"emissions into the box are scaled by an emission scale factor\n",
"as well as divided by boundary layer height."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "b087e326-12fa-4980-bb48-e9931b37e5fd",
"metadata": {},
"outputs": [],
"source": [
"AERO_DIST_INIT = [\n",
" {\n",
" \"init_small\": {\n",
" \"mass_frac\": [{\"SO4\": [1]}, {\"OC\": [1.375]}, {\"NH4\": [0.375]}],\n",
" \"diam_type\": \"geometric\",\n",
" \"mode_type\": \"log_normal\",\n",
" \"num_conc\": 3.2e9 / si.m**3,\n",
" \"geom_mean_diam\": 0.02 * si.um,\n",
" \"log10_geom_std_dev\": 0.161,\n",
" },\n",
" \"init_large\": {\n",
" \"mass_frac\": [{\"SO4\": [1]}, {\"OC\": [1.375]}, {\"NH4\": [0.375]}],\n",
" \"diam_type\": \"geometric\",\n",
" \"mode_type\": \"log_normal\",\n",
" \"num_conc\": 2.9e9 / si.m**3,\n",
" \"geom_mean_diam\": 0.16 * si.um,\n",
" \"log10_geom_std_dev\": 0.217,\n",
" },\n",
" }\n",
"]\n",
"\n",
"aero_dist_init = ppmc.AeroDist(aero_data, AERO_DIST_INIT)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "318eeecd-10ab-4190-88c6-3a952784239e",
"metadata": {},
"outputs": [],
"source": [
"AERO_DIST_EMIT = {\n",
" \"gasoline\": {\n",
" \"mass_frac\": [{\"OC\": [0.8]}, {\"BC\": [0.2]}],\n",
" \"diam_type\": \"geometric\",\n",
" \"mode_type\": \"log_normal\",\n",
" \"num_conc\": 5e7 / si.m**3,\n",
" \"geom_mean_diam\": 5e-8 * si.m,\n",
" \"log10_geom_std_dev\": 0.24,\n",
" },\n",
" \"diesel\": {\n",
" \"mass_frac\": [{\"OC\": [0.3]}, {\"BC\": [0.7]}],\n",
" \"diam_type\": \"geometric\",\n",
" \"mode_type\": \"log_normal\",\n",
" \"num_conc\": 1.6e8 / si.m**3,\n",
" \"geom_mean_diam\": 5e-8 * si.m,\n",
" \"log10_geom_std_dev\": 0.24,\n",
" },\n",
" \"cooking\": {\n",
" \"mass_frac\": [{\"OC\": [1]}],\n",
" \"diam_type\": \"geometric\",\n",
" \"mode_type\": \"log_normal\",\n",
" \"num_conc\": 9e6 / si.m**3,\n",
" \"geom_mean_diam\": 8.64e-8 * si.m,\n",
" \"log10_geom_std_dev\": 0.28,\n",
" },\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "998bd058-5b69-4e91-b591-65de2194692d",
"metadata": {},
"source": [
"#### Emitted gas species"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "7da2a4e6-7fb3-46bd-a9d2-5a64c18e4c22",
"metadata": {},
"outputs": [],
"source": [
"gas_emit_times = [0, 3600, 7200, 10800, 14400, 18000, 21600, 25200, 28800, 32400, 36000,\n",
" 39600, 43200, 46800, 50400, 54000, 57600, 61200, 64800, 68400, 72000,\n",
" 75600, 79200, 82800, 90000, 93600, 97200, 100800, 104400, 108000]\n",
"\n",
"gas_emit_rates = np.zeros(len(gas_emit_times))\n",
"gas_emit_rates[0:12] = .5\n",
"\n",
"SO2 = [4.234E-09, 5.481E-09, 5.089E-09, 5.199E-09, 5.221E-09, 5.284E-09, 5.244E-09,\n",
" 5.280E-09, 5.560E-09, 5.343E-09, 4.480E-09, 3.858E-09, 3.823E-09, 3.607E-09,\n",
" 3.533E-09, 3.438E-09, 2.866E-09, 2.667E-09, 2.636E-09, 2.573E-09, 2.558E-09,\n",
" 2.573E-09, 2.715E-09, 3.170E-09, 4.2344E-09, 5.481E-09, 5.089E-09, 5.199E-09,\n",
" 5.221E-09, 5.284E-09]\n",
"\n",
"NO2 = [3.024E-09, 3.334E-09, 3.063E-09, 3.281E-09, 3.372E-09, 3.523E-09, 3.402E-09,\n",
" 3.551E-09, 3.413E-09, 3.985E-09, 3.308E-09, 2.933E-09, 2.380E-09, 1.935E-09,\n",
" 1.798E-09, 1.537E-09 , 9.633E-10, 8.873E-10, 7.968E-10, 6.156E-10, 5.920E-10,\n",
" 6.320E-10, 9.871E-10, 1.901E-09, 3.024E-09, 3.334E-09, 3.063E-09, 3.281E-09,\n",
" 3.372E-09, 3.523E-09]\n",
"\n",
"NO = [5.749E-08, 6.338E-08, 5.825E-08, 6.237E-08, 6.411E-08, 6.699E-08, 6.468E-08,\n",
" 6.753E-08, 6.488E-08, 7.575E-08, 6.291E-08, 5.576E-08, 4.524E-08, 3.679E-08,\n",
" 3.419E-08, 2.924E-08, 1.832E-08, 1.687E-08, 1.515E-08, 1.171E-08, 1.125E-08,\n",
" 1.202E-08, 1.877E-08, 3.615E-08, 5.749E-08, 6.338E-08, 5.825E-08, 6.237E-08,\n",
" 6.411E-08, 6.699E-08]\n",
"\n",
"CO = [7.839E-07, 5.837E-07, 4.154E-07, 4.458E-07, 4.657E-07, 4.912E-07, 4.651E-07,\n",
" 4.907E-07, 6.938E-07, 8.850E-07, 8.135E-07, 4.573E-07, 3.349E-07, 2.437E-07,\n",
" 2.148E-07, 1.662E-07, 8.037E-08, 7.841E-08, 6.411E-08, 2.551E-08, 2.056E-08,\n",
" 3.058E-08, 1.083E-07, 3.938E-07, 7.839E-07, 5.837E-07, 4.154E-07, 4.458E-07,\n",
" 4.657E-07, 4.912E-07]\n",
"\n",
"NH3 = [8.93E-09, 8.705E-09, 1.639E-08, 1.466E-08, 1.6405E-08, 1.8805E-08, 1.65E-08,\n",
" 1.8045E-08, 1.347E-08, 6.745E-09, 5.415E-09, 2.553E-09, 2.087E-09, 2.2885E-09,\n",
" 2.7265E-09, 2.7338E-09, 9.96E-10, 2.707E-09, 9.84E-10, 9.675E-10, 9.905E-10,\n",
" 1.0345E-09, 1.0825E-09, 2.7465E-09, 8.93E-09, 8.705E-09, 1.639E-08, 1.466E-08,\n",
" 1.6405E-08, 1.8805E-08]\n",
"\n",
"HCHO = [4.061E-09, 3.225E-09, 2.440E-09, 2.639E-09, 2.754E-09, 2.888E-09, 2.741E-09,\n",
" 2.885E-09, 4.088E-09, 5.186E-09, 4.702E-09, 2.601E-09, 1.923E-09, 1.412E-09,\n",
" 1.252E-09, 9.776E-10, 4.687E-10, 4.657E-10, 3.836E-10, 1.717E-10, 1.448E-10,\n",
" 1.976E-10, 6.193E-10, 2.090E-09, 4.061E-09, 3.225E-09, 2.440E-09, 2.639E-09,\n",
" 2.754E-09, 2.888E-09]\n",
"\n",
"ALD2 = [1.702E-09, 1.283E-09, 9.397E-10, 1.024E-09, 1.076E-09, 1.132E-09, 1.068E-09,\n",
" 1.130E-09, 1.651E-09, 2.132E-09, 1.985E-09, 1.081E-09, 7.847E-10, 5.676E-10,\n",
" 5.003E-10, 3.838E-10, 1.784E-10, 1.766E-10, 1.430E-10, 5.173E-11, 4.028E-11,\n",
" 6.349E-11, 2.428E-10, 8.716E-10, 1.7022E-09, 1.283E-09, 9.397E-10, 1.024E-09,\n",
" 1.076E-09, 1.132E-09]\n",
"\n",
"ETH = [1.849E-08, 1.391E-08, 1.010E-08, 1.095E-08, 1.148E-08, 1.209E-08, 1.142E-08,\n",
" 1.205E-08, 1.806E-08, 2.320E-08, 2.149E-08, 1.146E-08, 8.384E-09, 6.124E-09,\n",
" 5.414E-09, 4.119E-09, 1.953E-09, 1.927E-09, 1.575E-09, 6.164E-10, 4.973E-10,\n",
" 7.420E-10, 2.653E-09, 9.477E-09, 1.849E-08, 1.391E-08, 1.010E-08, 1.095E-08,\n",
" 1.148E-08, 1.209E-08]\n",
"\n",
"OLEI = [5.948E-09, 4.573E-09, 3.374E-09, 3.668E-09, 3.851E-09, 4.050E-09, 3.841E-09,\n",
" 4.052E-09, 6.094E-09, 7.795E-09, 7.215E-09, 3.738E-09, 2.718E-09, 1.973E-09,\n",
" 1.729E-09, 1.338E-09, 6.333E-10, 6.394E-10, 5.126E-10, 2.089E-10, 1.708E-10,\n",
" 2.480E-10, 8.947E-10, 3.057E-09, 5.948E-09, 4.573E-09, 3.374E-09, 3.668E-09,\n",
" 3.851E-09, 4.050E-09]\n",
"\n",
"OLET = [5.948E-09, 4.573E-09, 3.374E-09, 3.668E-09, 3.851E-09, 4.050E-09, 3.841E-09,\n",
" 4.052E-09, 6.094E-09, 7.795E-09, 7.215E-09, 3.738E-09, 2.718E-09, 1.973E-09,\n",
" 1.729E-09, 1.338E-09, 6.333E-10, 6.394E-10, 5.126E-10, 2.089E-10, 1.708E-10,\n",
" 2.480E-10, 8.947E-10, 3.057E-09, 5.948E-09, 4.573E-09, 3.374E-09, 3.668E-09,\n",
" 3.851E-09, 4.050E-09]\n",
"\n",
"TOL = [6.101E-09, 8.706E-09, 7.755E-09, 8.024E-09, 8.202E-09, 8.410E-09, 8.218E-09,\n",
" 8.407E-09, 1.020E-08, 1.139E-08, 7.338E-09, 4.184E-09, 3.078E-09, 2.283E-09,\n",
" 2.010E-09, 1.575E-09, 8.966E-10, 6.705E-10, 5.395E-10, 2.462E-10, 2.106E-10,\n",
" 2.852E-10, 9.300E-10, 3.144E-09, 6.101E-09, 8.706E-09, 7.755E-09, 8.024E-09,\n",
" 8.202E-09, 8.410E-09]\n",
"\n",
"XYL = [5.599E-09, 4.774E-09, 3.660E-09, 3.909E-09, 4.060E-09, 4.239E-09, 4.060E-09,\n",
" 4.257E-09, 6.036E-09, 7.448E-09, 6.452E-09, 3.435E-09, 2.525E-09, 1.859E-09,\n",
" 1.650E-09, 1.302E-09, 6.852E-10, 6.773E-10, 5.437E-10, 2.697E-10, 2.358E-10,\n",
" 3.059E-10, 8.552E-10, 2.861E-10, 5.599E-09, 4.774E-09, 3.660E-09, 3.909E-09,\n",
" 4.060E-09, 4.239E-09]\n",
"\n",
"AONE = [7.825E-10, 2.858E-09, 2.938E-09, 2.947E-09, 2.948E-09, 2.951E-09, 2.947E-09,\n",
" 2.954E-09, 3.032E-09, 2.766E-09, 1.313E-09, 1.015E-09, 8.363E-10, 7.040E-10,\n",
" 6.404E-10, 6.264E-10, 5.661E-10, 1.538E-10, 1.500E-10, 1.395E-10, 1.476E-10,\n",
" 1.503E-10, 2.256E-10, 4.244E-10, 7.825E-10, 2.858E-09, 2.938E-09, 2.947E-09,\n",
" 2.948E-09, 2.951E-09]\n",
"\n",
"PAR = [1.709E-07, 1.953E-07, 1.698E-07, 1.761E-07, 1.808E-07, 1.865E-07, 1.822E-07,\n",
" 1.8599E-07, 2.412E-07, 2.728E-07, 2.174E-07, 1.243E-07, 9.741E-08, 7.744E-08,\n",
" 6.931E-08, 5.805E-08, 3.900E-08, 3.317E-08, 2.956E-08, 2.306E-08, 2.231E-08,\n",
" 2.395E-08, 4.284E-08, 9.655E-08, 1.709E-07, 1.953E-07, 1.698E-07, 1.761E-07,\n",
" 1.808E-07, 1.865E-07]\n",
"\n",
"ISOP = [2.412E-10, 2.814E-10, 3.147E-10, 4.358E-10, 5.907E-10, 6.766E-10, 6.594E-10,\n",
" 5.879E-10, 5.435E-10, 6.402E-10, 5.097E-10, 9.990E-11, 7.691E-11, 5.939E-11,\n",
" 5.198E-11, 4.498E-11, 3.358E-11, 2.946E-11, 2.728E-11, 2.183E-11, 1.953E-11,\n",
" 1.890E-11, 2.948E-11, 1.635E-10, 2.412E-10, 2.814E-10, 3.147E-10, 4.358E-10,\n",
" 5.907E-10, 6.766E-10]\n",
"\n",
"CH3OH = [2.368E-10, 6.107E-10, 6.890E-10, 6.890E-10, 6.890E-10, 6.889E-10, 6.886E-10,\n",
" 6.890E-10, 6.890E-10, 5.414E-10, 3.701E-10, 2.554E-10, 1.423E-10, 6.699E-11,\n",
" 2.912E-11, 2.877E-11, 2.825E-11, 2.056E-12, 2.056E-12, 2.056E-12, 2.435E-12,\n",
" 2.435E-12, 4.030E-11, 1.168E-10, 2.368E-10, 6.107E-10, 6.890E-10, 6.890E-10,\n",
" 6.890E-10, 6.889E-10]\n",
"\n",
"ANOL = [5.304E-09, 7.960E-09, 7.649E-09, 7.649E-09, 7.432E-09, 7.428E-09,\n",
" 7.431E-09, 7.434E-09, 7.434E-09, 6.979E-09,5.666E-09, 4.361E-09, 4.148E-09,\n",
" 3.289E-09, 2.858E-09, 2.856E-09, 1.127E-09, 9.615E-10, 9.616E-10, 9.616E-10,\n",
" 9.654E-10, 9.654E-10, 1.397E-09, 2.264E-09, 5.304E-09, 7.960E-09, 7.649E-09,\n",
" 7.649E-09, 7.432E-09, 7.428E-09]\n",
"\n",
"emit_gas = [\n",
" {\"time\": gas_emit_times},\n",
" {\"rate\": list(gas_emit_rates)},\n",
" {\"SO2\": SO2},\n",
" {\"NO\": NO},\n",
" {\"NO2\": NO2},\n",
" {\"CO\": CO},\n",
" {\"NH3\": NH3},\n",
" {\"HCHO\": HCHO},\n",
" {\"ALD2\": ALD2},\n",
" {\"ETH\": ETH},\n",
" {\"OLEI\": OLEI},\n",
" {\"OLET\": OLET},\n",
" {\"TOL\": TOL},\n",
" {\"XYL\": XYL},\n",
" {\"AONE\": AONE},\n",
" {\"PAR\": PAR},\n",
" {\"ISOP\": ISOP},\n",
" {\"CH3OH\": CH3OH},\n",
" {\"ANOL\": ANOL},\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "342a5765-7cff-4dc2-b4a9-60b239d23fe9",
"metadata": {},
"source": [
"#### Environmental state (EnvState)\n",
"\n",
"``ppmc.EnvState`` consists of environmental values for the current time of the simulation,\n",
"some of which are fixed and some of which are time varying."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "bc0e1eca-88ad-4443-a3d5-14d58fae7866",
"metadata": {},
"outputs": [],
"source": [
"env_state = ppmc.EnvState(\n",
" {\n",
" \"rel_humidity\": 0.95,\n",
" \"latitude\": 0,\n",
" \"longitude\": 0,\n",
" \"altitude\": 0 * si.m,\n",
" \"start_time\": 21600 * si.s,\n",
" \"start_day\": 200,\n",
" }\n",
")"
]
},
{
"cell_type": "markdown",
"id": "493192e8-c928-43a6-9d67-ffd1519121ac",
"metadata": {},
"source": [
"#### Describing the time evolution of the environment\n",
"\n",
"PartMC requires time series of pressure, temperature and boundary layer heights.\n",
"Water mixing ratio is kept constant and the relative humidity is updated accordingly."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "2cd76808-4552-47ee-96cd-8e48bfafb3cf",
"metadata": {},
"outputs": [],
"source": [
"time_timeseries = list(np.linspace(0,24*3600,25))\n",
"pressure_timeseries = list(np.ones(25) * 1e5)\n",
"temp_timeseries = [290.016,292.5, 294.5, 296.112, 297.649, 299.049, 299.684, 299.509,299.002,\n",
" 298.432, 296.943, 295.153, 293.475, 292.466, 291.972, 291.96, 291.512,\n",
" 291.481, 290.5, 290.313, 290.317, 290.362, 290.245, 290.228, 291.466]\n",
"height_timeseries = [171.045, 228.210, 296.987, 366.002, 410.868, 414.272, 417.807,414.133,\n",
" 397.465, 376.864, 364.257, 352.119, 338.660, 322.028, 305.246, 258.497, \n",
" 240.478, 187.229, 145.851, 128.072, 110.679, 97.628, 93.034, 93.034, 93.034]"
]
},
{
"cell_type": "markdown",
"id": "5ea83f30-4a47-4351-ac70-43a83b2a42fe",
"metadata": {},
"source": [
"#### Background values\n",
"\n",
"Background air is mixed in due to dillution effects both by the prescribed rate of dillution\n",
"and changes in boundary layer height. In Riemer et al 2009, the gas mixing ratios and aerosol distributions \n",
"are identical to those of the initial conditions."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "f02c9163-e7d9-4eaa-93ea-4c914918bc4a",
"metadata": {},
"outputs": [],
"source": [
"AERO_DIST_BACKGROUND = {\n",
" \"back_small\": {\n",
" \"mass_frac\": [{\"SO4\": [1]}, {\"OC\": [1.375]}, {\"NH4\": [0.375]}],\n",
" \"diam_type\": \"geometric\",\n",
" \"mode_type\": \"log_normal\",\n",
" \"num_conc\": 3.2e9 / si.m**3,\n",
" \"geom_mean_diam\": 0.02 * si.um,\n",
" \"log10_geom_std_dev\": 0.161,\n",
" },\n",
" \"back_large\": {\n",
" \"mass_frac\": [{\"SO4\": [1]}, {\"OC\": [1.375]}, {\"NH4\": [0.375]}],\n",
" \"diam_type\": \"geometric\",\n",
" \"mode_type\": \"log_normal\",\n",
" \"num_conc\": 2.9e9 / si.m**3,\n",
" \"geom_mean_diam\": 0.16 * si.um,\n",
" \"log10_geom_std_dev\": 0.217,\n",
" },\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "d8b5d238-121e-4cc0-af71-33165a5965d3",
"metadata": {},
"outputs": [],
"source": [
"times = [0 * si.s]\n",
"back_gas = [{\"time\": times},\n",
" {\"rate\": [1.5e-5 / si.s]},\n",
" {\"NO\": [0.1E+00]},\n",
" {\"NO2\": [1.0E+00]},\n",
" {\"HNO3\": [1.0E+00]},\n",
" {\"O3\": [5.0E+01]},\n",
" {\"H2O2\": [1.1E+00]},\n",
" {\"CO\": [2.1E+02]},\n",
" {\"SO2\": [0.8E+00]},\n",
" {\"NH3\": [0.5E+00]},\n",
" {\"HCl\": [0.7E+00]},\n",
" {\"CH4\": [2.2E+03]},\n",
" {\"C2H6\": [1.0E+00]},\n",
" {\"HCHO\": [1.2E+00]},\n",
" {\"CH3OH\": [1.2E-01]},\n",
" {\"CH3OOH\": [0.5E+00]},\n",
" {\"ALD2\": [1.0E+00]},\n",
" {\"PAR\": [2.0E+00]},\n",
" {\"AONE\": [1.0E+00]},\n",
" {\"ETH\": [0.2E+00]},\n",
" {\"OLET\": [2.3E-02]},\n",
" {\"OLEI\": [3.1E-04]},\n",
" {\"TOL\": [0.1E+00]},\n",
" {\"XYL\": [0.1E+00]},\n",
" {\"ONIT\": [0.1E+00]},\n",
" {\"PAN\": [0.8E+00]},\n",
" {\"RCOOH\": [0.2E+00]},\n",
" {\"ROOH\": [2.5E-02]},\n",
" {\"ISOP\": [0.5E+00]}\n",
" ]"
]
},
{
"cell_type": "markdown",
"id": "2d92866d-f8cf-4837-8fdb-9bb218ac96e0",
"metadata": {},
"source": [
"#### Finalizing scenario information (Scenario)"
]
},
{
"cell_type": "markdown",
"id": "cfc5e15b-9392-4d7e-a999-3ba6541f0688",
"metadata": {},
"source": [
"The ``ppmc.Scenario`` object contains all information necessary for the time evolution of the values\n",
"in the simulation. As time advances in the simulation, PyPartMC updates `env_state` based on\n",
"these prescribed environmental time series and emits gases and aerosols accordingly."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "920e41e3",
"metadata": {},
"outputs": [],
"source": [
"scenario = ppmc.Scenario(\n",
" gas_data,\n",
" aero_data,\n",
" {\n",
" \"temp_profile\": [{\"time\": time_timeseries}, {\"temp\": temp_timeseries}],\n",
" \"pressure_profile\": [\n",
" {\"time\": time_timeseries},\n",
" {\"pressure\": pressure_timeseries},\n",
" ],\n",
" \"height_profile\": [{\"time\": time_timeseries}, {\"height\": height_timeseries}],\n",
" \"gas_emissions\": emit_gas,\n",
" \"gas_background\": back_gas,\n",
" \"aero_emissions\": [\n",
" {\"time\": [0 * si.s, 12 * 3600 * si.s]},\n",
" {\"rate\": [1 / si.s, 0 / si.s]},\n",
" {\"dist\": [[AERO_DIST_EMIT],[AERO_DIST_EMIT]]},\n",
" ],\n",
" \"aero_background\": [\n",
" {\"time\": [0 * si.s]},\n",
" {\"rate\": [1.5e-5 / si.s]},\n",
" {\"dist\": [[AERO_DIST_BACKGROUND]]},\n",
" ],\n",
" \"loss_function\": \"none\",\n",
" },\n",
")"
]
},
{
"cell_type": "markdown",
"id": "5a7c53bd-a851-444b-83a1-ba01a04a6651",
"metadata": {},
"source": [
"Here, the initial values of the environment is set based on the ``ppmc.Scenario`` object `scenario`"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "6722ba83",
"metadata": {},
"outputs": [],
"source": [
"T_INITIAL = 0.0\n",
"scenario.init_env_state(env_state, T_INITIAL)"
]
},
{
"cell_type": "markdown",
"id": "9005d238-07a7-48c6-ba49-01d3e77e1fa6",
"metadata": {},
"source": [
"Simulation parameters are contained in the ``ppmc.RunPartOpt`` object.\n",
"Options include simulation length (``t_max``), time step size (``del_t``)\n",
"as well as other numerical settings. Additionally, model processes can be enabled or disabled.\n",
"In this simulation, Brownian coagulation is enabled with ``do_coagulation\": True`` and ``\"coag_kernel\": \"brown\"``."
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "d1c80c6a-737c-405c-81cb-93da0fe3eae2",
"metadata": {},
"outputs": [],
"source": [
"run_part_opt = ppmc.RunPartOpt(\n",
" {\n",
" \"output_prefix\": \"urban_plume\",\n",
" \"do_coagulation\": True,\n",
" \"coag_kernel\": \"brown\",\n",
" \"t_max\": 86400 * si.s,\n",
" \"del_t\": 60 * si.s,\n",
" }\n",
")"
]
},
{
"cell_type": "markdown",
"id": "50bc044d-c6ce-4a06-b80e-c124692023a3",
"metadata": {},
"source": [
"#### Sampling the initial aerosol distribution\n",
"\n",
"Before beginning the simulation, the initial condition for aerosols must be sampled."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "d8d9c8fd",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"257"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"N_PART = 1000\n",
"aero_state = ppmc.AeroState(aero_data, N_PART, 'nummass_source')\n",
"aero_state.dist_sample(\n",
" aero_dist_init,\n",
" sample_prop=1.0,\n",
" create_time=0.0,\n",
" allow_doubling=True,\n",
" allow_halving=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "5c8aef2b",
"metadata": {},
"outputs": [],
"source": [
"camp_core = ppmc.CampCore()\n",
"photolysis = ppmc.Photolysis()"
]
},
{
"cell_type": "markdown",
"id": "2e63d9d7-b3f4-4875-83d0-a0d9d4d93d31",
"metadata": {},
"source": [
"#### Running the simulation"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "0f7c29fe",
"metadata": {},
"outputs": [],
"source": [
"N_STEPS = int(run_part_opt.t_max / run_part_opt.del_t)\n",
"num_conc = np.zeros(N_STEPS + 1)\n",
"num_conc[0] = aero_state.total_num_conc\n",
"mass_conc = np.zeros(N_STEPS + 1)\n",
"mass_conc[0] = aero_state.total_mass_conc\n",
"time = np.zeros(N_STEPS + 1)\n",
"gas_mix_rat = np.zeros((N_STEPS + 1, gas_state.n_spec))\n",
"gas_mix_rat[0, :] = gas_state.mix_rats\n",
"\n",
"height = np.zeros((N_STEPS + 1))\n",
"temperature = np.zeros((N_STEPS + 1))\n",
"rh = np.zeros((N_STEPS + 1))\n",
"\n",
"height[0] = env_state.height\n",
"temperature[0] = env_state.temp\n",
"rh[0] = env_state.rh\n",
"\n",
"diam_grid = ppmc.BinGrid(30, \"log\", 1e-9, 1e-6)\n",
"dists = []\n",
"dry_diameters = aero_state.dry_diameters\n",
"num_concs = aero_state.num_concs\n",
"dists.append(ppmc.histogram_1d(diam_grid, dry_diameters, num_concs))\n",
"\n",
"last_output_time = 0.\n",
"last_progress_time = 0.\n",
"i_output = 1\n",
"\n",
"for i_time in range(1,N_STEPS + 1):\n",
" (last_output_time, last_progress_time, i_output) = ppmc.run_part_timestep(\n",
" scenario,\n",
" env_state,\n",
" aero_data,\n",
" aero_state,\n",
" gas_data,\n",
" gas_state,\n",
" run_part_opt,\n",
" camp_core,\n",
" photolysis,\n",
" i_time,\n",
" T_INITIAL,\n",
" last_output_time,\n",
" last_progress_time,\n",
" i_output\n",
" )\n",
" num_conc[i_time] = aero_state.total_num_conc\n",
" mass_conc[i_time] = aero_state.total_mass_conc\n",
" time[i_time] = env_state.elapsed_time\n",
" gas_mix_rat[i_time, :] = gas_state.mix_rats\n",
" height[i_time] = env_state.height\n",
" temperature[i_time] = env_state.temp\n",
" rh[i_time] = env_state.rh\n",
" if np.mod(i_time * run_part_opt.del_t, 3600.0) == 0:\n",
" dry_diameters = aero_state.dry_diameters\n",
" num_concs = aero_state.num_concs\n",
" dists.append(ppmc.histogram_1d(diam_grid, dry_diameters, num_concs))"
]
},
{
"cell_type": "markdown",
"id": "cee6acb2-d436-48e8-8f0a-05b8fb149cf1",
"metadata": {},
"source": [
"### Analysis"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "82c0cebb",
"metadata": {},
"outputs": [],
"source": [
"plt.rcParams.update({'font.size': 9})\n",
"plt.rcParams.update({'figure.figsize': (3.08,2.5)})\n",
"plt.rcParams.update({\"axes.grid\" : True})"
]
},
{
"cell_type": "markdown",
"id": "78361e38-45db-45a9-a080-d7adea2f3ee9",
"metadata": {},
"source": [
"#### Environmental parameters (Figure 3)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "47474cd3",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "a595fb37e3a14de9a3baf022dc04f05d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(HTML(value=\"./tmph6o2frx4.pdf
\"), HTML(value…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(time,temperature,'r')\n",
"plt.ylabel('Temperature (K)', color='r')\n",
"plt.ylim([275,300])\n",
"plt.xticks(np.linspace(0, time[-1], 5))\n",
"plt.xlim([0,time[-1]])\n",
"plt.xlabel('Time (s)')\n",
"plt.twinx()\n",
"plt.plot(time,rh*100,'g')\n",
"plt.ylabel('Relative humidity (%)', color='g')\n",
"plt.ylim([0,100])\n",
"show_plot()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "e848f60b",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "426a3207cafb45bab34bcd7c914376be",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(HTML(value=\"./tmpff4f0fhr.pdf
\"), HTML(value…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(time,height)\n",
"plt.xticks(np.linspace(0, time[-1], 5))\n",
"plt.xlim([0,time[-1]])\n",
"plt.xlabel('Time (s)')\n",
"plt.ylim([0,500])\n",
"plt.ylabel('Boundary layer height (m)')\n",
"show_plot()"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "c85a622a",
"metadata": {},
"outputs": [],
"source": [
"def set_tickmarks(axes, n_ticks):\n",
" ylims = axes.get_ylim()\n",
" if np.log10(ylims[0]) > 1:\n",
" val = -int(np.ceil(np.abs(np.log10(ylims[0])))) + 1\n",
" else:\n",
" val = int(np.ceil(np.abs(np.log10(ylims[0])))) + 1 \n",
" ymin = round(ylims[0] - .1 * ylims[0], val)\n",
" ymax = round(ylims[1] + .1 * ylims[1], val)\n",
" plt.ylim([ymin, ymax])\n",
" plt.yticks(np.linspace(ymin, ymax, n_ticks))"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "23d921e4-81fc-4ce7-98d4-899c5862813c",
"metadata": {},
"outputs": [],
"source": [
"#### Evolution of gas-phase species"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "b2012bfa-be9c-4ed1-a85f-e842c75ec14e",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "bd7179d9160447248458ea37a199a21d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(HTML(value=\"./tmp20sh_hvz.pdf
\"), HTML(value…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"gases = [\"NO\", \"NO2\", \"O3\", \"HNO3\", \"SO2\", \"NH3\"]\n",
"for i_spec, spec in enumerate(gases):\n",
" i_spec = gas_data.spec_by_name(spec)\n",
" l, = plt.plot(time, gas_mix_rat[:, i_spec], label=spec)\n",
"plt.xlabel(\"Time (s)\")\n",
"plt.ylabel(\"Mixing ratio (ppb)\")\n",
"plt.xticks(np.linspace(0, time[-1], 5))\n",
"plt.legend()\n",
"show_plot()"
]
},
{
"cell_type": "markdown",
"id": "8ecd67fb-fbd3-4342-9fc8-38faac198742",
"metadata": {},
"source": [
"#### Bulk Aerosol Evolution"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "8e1b89e0",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "1437405f06154a58b6204ba34d05da5d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(HTML(value=\"./tmp0gk79ve0.pdf
\"), HTML(value…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(time, mass_conc, \"b\", label=\"mass conc\")\n",
"plt.ylabel(\"Mass concentration (kg m$^{-3}$)\", color='b')\n",
"plt.xlabel(\"Time (s)\")\n",
"set_tickmarks(plt.gca(), 5)\n",
"plt.twinx()\n",
"plt.plot(time, num_conc, \"g\", label=\"num conc\")\n",
"plt.xticks(np.linspace(0, time[-1], 5))\n",
"plt.xlim([time[0],time[-1]])\n",
"set_tickmarks(plt.gca(), 5)\n",
"plt.ylabel(r\"Number concentration ($\\#$ m$^{-3}$)\", color='g')\n",
"show_plot()"
]
},
{
"cell_type": "markdown",
"id": "e12a179c-ad43-43b0-a8ee-77c453c44ef1",
"metadata": {},
"source": [
"#### Aerosol Size Distribution Evolution"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "faa1de28",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "0620030ea4914349a65e7246897a4d4b",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(HTML(value=\"./tmptsqb3a0x.pdf
\"), HTML(value…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(diam_grid.centers, dists[0],label='$t = 0$ h')\n",
"plt.plot(diam_grid.centers, dists[6],label='$t = 6$ h')\n",
"plt.plot(diam_grid.centers, dists[12],label='$t = 12$ h')\n",
"plt.plot(diam_grid.centers, dists[24],label='$t = 24$ h')\n",
"plt.xscale(\"log\")\n",
"plt.xlabel(\"Dry diameter (m)\")\n",
"plt.ylabel(r\"Number concentration $n(D)$ ($\\#$ m$^{-3}$)\")\n",
"plt.ylim(bottom=0)\n",
"plt.legend()\n",
"plt.xlim([diam_grid.edges[0],diam_grid.edges[-1]])\n",
"show_plot()"
]
},
{
"cell_type": "markdown",
"id": "c4cbc7f6-b650-4821-825d-efc958947de9",
"metadata": {},
"source": [
"#### Aerosol Mixing State Evolution\n",
"\n",
"While the previous aerosol figures give an overview of aerosol size distribution and composition\n",
"just like traditional size-distribution-based models, they do not address the issue of mixing state.\n",
"To show how the mixing state evolved over the course of the simulation we display the data,\n",
"where the two-dimensional number distribution is plotted as a function of dry diameter and\n",
"dry mass fraction of BC.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "7015860b",
"metadata": {},
"outputs": [],
"source": [
"mass_frac_grid = ppmc.BinGrid(100, \"linear\", 0, 1)\n",
"mass_frac_histogram = []\n",
"num_concs = aero_state.num_concs\n",
"dry_diameters = aero_state.dry_diameters\n",
"bc_masses = aero_state.masses(include=[\"BC\"])\n",
"dry_masses = aero_state.masses(exclude=[\"H2O\"])\n",
"species_mass_frac = np.array(bc_masses) / np.array(dry_masses)\n",
"vals = ppmc.histogram_2d(\n",
" diam_grid, dry_diameters, mass_frac_grid, species_mass_frac, num_concs\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "07fabfba",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "78d291d68ef94578a6bc27301d1c9881",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(HTML(value=\"./tmp0qfhiah8.pdf
\"), HTML(value…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.pcolormesh(\n",
" diam_grid.edges,\n",
" np.array(mass_frac_grid.edges)*100,\n",
" np.array(vals).T / 1e6,\n",
" norm=matplotlib.colors.LogNorm(),\n",
")\n",
"plt.xscale(\"log\")\n",
"plt.xlim([1e-8, 1e-6])\n",
"plt.colorbar(label=r\"Number concentration ($\\#$ cm$^{-3}$)\")\n",
"plt.xlabel(\"Dry diameter (m)\")\n",
"plt.ylabel(\"BC mass fraction (%)\")\n",
"show_plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "21f7a9ab",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}