{
"cells": [
{
"cell_type": "markdown",
"id": "6f3ab7ce",
"metadata": {},
"source": [
"[](https://github.com/open-atmos/PyPartMC/blob/main/examples/cloud_parcel.ipynb) \n",
"[](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/cloud_parcel.ipynb) \n",
"[](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/cloud_parcel.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) 2024 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": "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",
"from open_atmos_jupyter_utils import show_plot\n",
"import PyPartMC as ppmc\n",
"from PyPartMC import si"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "df8d1a84",
"metadata": {},
"outputs": [],
"source": [
"gas_data = ppmc.GasData((\n",
" \"H2SO4\", \"HNO3\", \"HCl\", \"NH3\", \"NO\", \"NO2\", \"NO3\", \"N2O5\", \"HONO\", \"HNO4\",\n",
" \"O3\", \"O1D\", \"O3P\", \"OH\", \"HO2\", \"H2O2\", \"CO\", \"SO2\", \"CH4\", \"C2H6\",\n",
" \"CH3O2\", \"ETHP\", \"HCHO\", \"CH3OH\", \"ANOL\", \"CH3OOH\", \"ETHOOH\", \"ALD2\",\n",
" \"HCOOH\", \"RCOOH\", \"C2O3\", \"PAN\", \"ARO1\", \"ARO2\", \"ALK1\", \"OLE1\", \"API1\",\n",
" \"API2\", \"LIM1\", \"LIM2\", \"PAR\", \"AONE\", \"MGLY\", \"ETH\", \"OLET\", \"OLEI\",\n",
" \"TOL\", \"XYL\", \"CRES\", \"TO2\", \"CRO\", \"OPEN\", \"ONIT\", \"ROOH\", \"RO2\", \"ANO2\",\n",
" \"NAP\", \"XO2\", \"XPAR\", \"ISOP\", \"ISOPRD\", \"ISOPP\", \"ISOPN\", \"ISOPO2\", \"API\",\n",
" \"LIM\", \"DMS\", \"MSA\", \"DMSO\", \"DMSO2\", \"CH3SO2H\", \"CH3SCH2OO\", \"CH3SO2\",\n",
" \"CH3SO3\", \"CH3SO2OO\", \"CH3SO2CH2OO\", \"SULFHOX\"\n",
"))"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "a2d7bad8",
"metadata": {},
"outputs": [],
"source": [
"env_state = ppmc.EnvState({\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",
"})"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "815283a0",
"metadata": {},
"outputs": [],
"source": [
"aero_data = ppmc.AeroData((\n",
" # density ions in soln (1) molecular weight kappa (1)\n",
" # \\ \\ / |\n",
" {\"SO4\": [1800 * si.kg / si.m**3, 1, 96.0 * si.g / si.mol, 0.00]},\n",
" {\"NO3\": [1800 * si.kg / si.m**3, 1, 62.0 * si.g / si.mol, 0.00]},\n",
" {\"Cl\": [2200 * si.kg / si.m**3, 1, 35.5 * si.g / si.mol, 0.00]},\n",
" {\"NH4\": [1800 * si.kg / si.m**3, 1, 18.0 * si.g / si.mol, 0.00]},\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, 1, 60.0 * si.g / si.mol, 0.00]},\n",
" {\"Na\": [2200 * si.kg / si.m**3, 1, 23.0 * si.g / si.mol, 0.00]},\n",
" {\"Ca\": [2600 * si.kg / si.m**3, 1, 40.0 * si.g / si.mol, 0.00]},\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.10]},\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",
"))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "c822823d",
"metadata": {},
"outputs": [],
"source": [
"gas_state = ppmc.GasState(gas_data)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "58706963",
"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",
"}\n",
"\n",
"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",
"}"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "c6a96b7d",
"metadata": {},
"outputs": [],
"source": [
"time_timeseries = [0, 1200]\n",
"pressure_timeseries = [1e5, 1e5]\n",
"temp_timeseries = [290, 280]\n",
"height_timeseries = [200, 200]\n",
"times = [0 * si.s]\n",
"gas_emit_times = [0]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "920e41e3",
"metadata": {},
"outputs": [],
"source": [
"scenario = ppmc.Scenario(\n",
" gas_data,\n",
" aero_data,\n",
" {\n",
" \"temp_profile\": [\n",
" {\"time\": time_timeseries},\n",
" {\"temp\": temp_timeseries}\n",
" ],\n",
" \"pressure_profile\": [\n",
" {\"time\": time_timeseries},\n",
" {\"pressure\": pressure_timeseries},\n",
" ],\n",
" \"height_profile\": [\n",
" {\"time\": time_timeseries},\n",
" {\"height\": height_timeseries}\n",
" ],\n",
" \"gas_emissions\": [\n",
" {\"time\": gas_emit_times},\n",
" {\"rate\": [0.] * len(gas_emit_times)},\n",
" ],\n",
" \"gas_background\": [\n",
" {\"time\": times},\n",
" {\"rate\": [0.0 / si.s] * len(times)},\n",
" ],\n",
" \"aero_emissions\": [\n",
" {\"time\": [0 * si.s, 12 * 3600 * si.s]},\n",
" {\"rate\": [0 / si.s, 0 / si.s]},\n",
" {\"dist\": [[AERO_DIST_EMIT], [AERO_DIST_EMIT]]},\n",
" ],\n",
" \"aero_background\": [\n",
" {\"time\": [0 * si.s]},\n",
" {\"rate\": [0 / si.s]},\n",
" {\"dist\": [[AERO_DIST_BACKGROUND]]},\n",
" ],\n",
" \"loss_function\": \"none\",\n",
" },\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "6722ba83",
"metadata": {},
"outputs": [],
"source": [
"T_INITIAL = 0.0\n",
"scenario.init_env_state(env_state, T_INITIAL)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "9781ca2f",
"metadata": {},
"outputs": [],
"source": [
"AERO_DIST_INIT = [{\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",
"aero_dist_init = ppmc.AeroDist(aero_data, AERO_DIST_INIT)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "d8d9c8fd",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"244"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"run_part_opt = ppmc.RunPartOpt({\n",
" \"output_prefix\": \"urban_plume\",\n",
" \"do_coagulation\": False,\n",
" \"t_max\": 600 * si.s,\n",
" \"del_t\": 1 * si.s,\n",
" \"do_condensation\": True\n",
"})\n",
"\n",
"N_PART = 500\n",
"aero_state = ppmc.AeroState(aero_data, N_PART, 'flat_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": 14,
"id": "10c018d8",
"metadata": {},
"outputs": [],
"source": [
"ppmc.condense_equilib_particles(env_state,aero_data, aero_state)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "5c8aef2b",
"metadata": {},
"outputs": [],
"source": [
"camp_core = ppmc.CampCore()\n",
"photolysis = ppmc.Photolysis()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "0f7c29fe",
"metadata": {},
"outputs": [],
"source": [
"N_STEPS = int(run_part_opt.t_max / run_part_opt.del_t)\n",
"\n",
"output = {\n",
" aero_state: ('total_num_conc', 'total_mass_conc'),\n",
" env_state: ('height', 'temp', 'rh', 'air_density', 'elapsed_time'),\n",
"}\n",
"\n",
"data = {\n",
" **{\n",
" attr: np.zeros(N_STEPS + 1)\n",
" for attrs in output.values()\n",
" for attr in attrs \n",
" },\n",
" **{\n",
" 'gas_mix_rat': np.zeros((N_STEPS + 1, gas_state.n_spec)),\n",
" 'dists': {}\n",
" }\n",
"}\n",
"\n",
"diam_grid = ppmc.BinGrid(50, \"log\", 1e-9 * si.m, 1e-4 * si.m)\n",
"\n",
"last_output_time = 0.\n",
"last_progress_time = 0.\n",
"i_output = 1\n",
"\n",
"for i_time in range(0, N_STEPS + 1):\n",
" if i_time != 0:\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",
" for obj, attrs in output.items():\n",
" for attr in attrs:\n",
" data[attr][i_time] = getattr(obj, attr)\n",
" data['gas_mix_rat'][i_time, :] = gas_state.mix_rats\n",
" if np.mod(i_time * run_part_opt.del_t, 60 * si.s) == 0:\n",
" data['dists'][i_time] = ppmc.histogram_1d(\n",
" diam_grid,\n",
" aero_state.diameters(),\n",
" np.asarray(aero_state.num_concs) / env_state.air_density\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 17,
"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": "code",
"execution_count": 18,
"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": "ebadf196d8c4493584448b2a6c35d599",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HTML(value=\"./tmpytdriw5t.pdf
\")"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(data['elapsed_time'], data['temp'], 'r')\n",
"plt.ylabel('Temperature (K)', color='r')\n",
"plt.ylim([275, 300])\n",
"plt.xticks(np.linspace(0, data['elapsed_time'][-1], 5))\n",
"plt.xlim([0, data['elapsed_time'][-1]])\n",
"plt.xlabel('Time (s)')\n",
"plt.twinx()\n",
"plt.plot(data['elapsed_time'], data['rh'] * 100, 'g')\n",
"plt.ylabel('Relative humidity (%)', color='g')\n",
"plt.ylim([50, 101])\n",
"show_plot()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"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": "be2d7363eaf84f649ecba610a8035378",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HTML(value=\"./tmp3ic9f1a4.pdf
\")"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(\n",
" data['elapsed_time'],\n",
" data['total_mass_conc'] / data['air_density'],\n",
" \"b\", label=\"mass conc\"\n",
")\n",
"plt.ylabel(r\"H2O mass mixing ratio (kg kg$_{\\rm dry air}^{-1}$)\", color='b')\n",
"plt.xlabel(\"Time (s)\")\n",
"plt.twinx()\n",
"plt.plot(\n",
" data['elapsed_time'],\n",
" data['total_num_conc'] / data['air_density'],\n",
" \"g\", label=\"num conc\"\n",
")\n",
"plt.xticks(np.linspace(0, data['elapsed_time'][-1], 5))\n",
"plt.xlim([data['elapsed_time'][0], data['elapsed_time'][-1]])\n",
"plt.ylabel(r\"Number density ($\\#$ kg$_{\\rm dry air}^{-1}$)\", color='g')\n",
"show_plot()"
]
},
{
"cell_type": "code",
"execution_count": 20,
"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": "4932404470a64d12a2addcfcb65edefd",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HTML(value=\"./tmp4_3c_tg2.pdf
\")"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"for i in (0, 5, 10):\n",
" plt.plot(\n",
" diam_grid.centers,\n",
" data['dists'][i * 60 * si.s / run_part_opt.del_t],\n",
" label=f'$t = {i}$ min'\n",
" )\n",
"plt.xscale(\"log\")\n",
"plt.xlabel(\"Diameter (m)\")\n",
"plt.ylabel(r\"Number mixing ratio $n(D)$ ($\\#$ kg$_{\\rm dry air}^{-1}$)\")\n",
"plt.ylim(bottom=0)\n",
"plt.legend()\n",
"plt.xlim(diam_grid.edges[0], diam_grid.edges[-1])\n",
"show_plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef17d66c-c058-4512-8da8-c0bc56856cb5",
"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.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}