diff --git a/.zenodo.json b/.zenodo.json
index 6c3be8b1..6482ced6 100644
--- a/.zenodo.json
+++ b/.zenodo.json
@@ -25,6 +25,10 @@
"affiliation": "University of California, Davis, CA, USA",
"name": "Ware, Emma"
},
+ {
+ "affiliation": "AGH University of Krakow, Kraków, Poland",
+ "name": "Adamus, Gracjan"
+ },
{
"affiliation": "University of Illinois Urbana-Champaign",
"name": "Riemer, Nicole",
diff --git a/examples/additive_coag_comparison.ipynb b/examples/additive_coag_comparison.ipynb
index 50af2f25..f17d161a 100644
--- a/examples/additive_coag_comparison.ipynb
+++ b/examples/additive_coag_comparison.ipynb
@@ -68,7 +68,7 @@
" if shutil.which('julia') is None:\n",
" !wget -q https://julialang-s3.julialang.org/bin/linux/x64/1.11/julia-1.11.3-linux-x86_64.tar.gz -O /tmp/julia.tar.gz; \\\n",
" tar -x -f /tmp/julia.tar.gz -C /usr/local --strip-components 1; \\\n",
- " rm /tmp/julia.tar.gz; \\\n"
+ " rm /tmp/julia.tar.gz;"
]
},
{
@@ -83,10 +83,11 @@
"import urllib\n",
"import json\n",
"import subprocess\n",
+ "import warnings\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from open_atmos_jupyter_utils.show_anim import show_anim \n",
- "# model-related imports have been moved to the specific model class cells"
+ "# note: model-related imports have been moved to the specific model class cells"
]
},
{
@@ -116,7 +117,7 @@
"SETTINGS[\"N_PLOT_STEPS\"] = SETTINGS[\"T_MAX_SEC\"] // SETTINGS[\"PLOT_TIME_STEP_SEC\"]\n",
"assert SETTINGS[\"N_PLOT_STEPS\"] * SETTINGS[\"PLOT_TIME_STEP_SEC\"] == SETTINGS[\"T_MAX_SEC\"]\n",
"\n",
- "#Load settings into json file for julia process\n",
+ "# Save settings into json file for julia process\n",
"with open('setup.json', 'w', encoding='UTF-8') as f:\n",
" json.dump(SETTINGS, f)\n",
"\n",
@@ -130,6 +131,14 @@
" self.settings = settings"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "26e72d27-d1ea-4840-b7f9-7470e378ce6f",
+ "metadata": {},
+ "source": [
+ "### Format for a new model run, search NEW_MODEL for lines to change"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 6,
@@ -137,7 +146,6 @@
"metadata": {},
"outputs": [],
"source": [
- "# Format for a new model run, search NEW_MODEL for lines to change\n",
"# pylint: disable=unnecessary-pass\n",
"class NewModelRun(Run):\n",
" def __init__(self,settings):\n",
@@ -342,10 +350,15 @@
" {\"H2O\": [1000 * ppmc.si.kg / ppmc.si.m**3, 0, 18.0 * ppmc.si.g / ppmc.si.mol, 0.00]},\n",
" ))\n",
" self.gas_state = ppmc.GasState(gas_data)\n",
- " placeholder_gas = [\n",
+ "\n",
+ " common = [\n",
" {\"time\": [0 * ppmc.si.s]},\n",
- " {\"rate\": [0 / ppmc.si.s]},\n",
- " {\"dist\": [[{\"placeholder\": {\n",
+ " {\"rate\": [0 / ppmc.si.s]}\n",
+ " ]\n",
+ " placeholder_gas = [\n",
+ " *common,\n",
+ " {\"dist\":\n",
+ " [[{\"placeholder\": {\n",
" \"mass_frac\": [{\"H2O\": [1]}],\n",
" \"diam_type\": \"geometric\",\n",
" \"mode_type\": \"log_normal\",\n",
@@ -365,8 +378,8 @@
" {\"pressure\": [100000]},\n",
" ],\n",
" \"height_profile\": [{\"time\": [0]}, {\"height\": [1000]}],\n",
- " \"gas_emissions\": placeholder_gas,\n",
- " \"gas_background\": placeholder_gas,\n",
+ " \"gas_emissions\": common,\n",
+ " \"gas_background\": common,\n",
" \"aero_emissions\": placeholder_gas,\n",
" \"aero_background\":placeholder_gas,\n",
" \"loss_function\": \"none\",\n",
@@ -462,7 +475,7 @@
},
{
"cell_type": "code",
- "execution_count": 17,
+ "execution_count": 10,
"id": "f7d54f29",
"metadata": {},
"outputs": [],
@@ -473,7 +486,7 @@
" 'https://raw.githubusercontent.com/emmacware/droplets.jl/REVISION/'\n",
" ).replace('REVISION', 'c3b5ae4edf12c7b10dc8759639f18de1267bc52b')\n",
" for path in (\n",
- " 'src/SDfunc/constants.jl', 'src/SDfunc/binning.jl','src/SDfunc/coalescence.jl',\n",
+ " 'src/SDfunc/constants.jl', 'src/SDfunc/binning.jl', 'src/SDfunc/coalescence.jl',\n",
" ):\n",
" with open('Droplets.jl-' + path.replace('/','-'), 'w', encoding='utf-8') as fout:\n",
" with urllib.request.urlopen(BASE_URL + path) as fin:\n",
@@ -481,7 +494,7 @@
" \n",
" code_to_write = \"\"\"\n",
" using Pkg\n",
- " Pkg.add([\"Combinatorics\", \"Distributions\", \"Random\",\"JSON\",\"Interpolations\"])\n",
+ " Pkg.add([\"Combinatorics\", \"Distributions\", \"Random\", \"JSON\", \"Interpolations\"])\n",
" using Random,Combinatorics,Distributions\n",
" include(\"Droplets.jl-src-SDfunc-constants.jl\")\n",
" include(\"Droplets.jl-src-SDfunc-coalescence.jl\")\n",
@@ -553,27 +566,22 @@
" return Droplets"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "7436416c-7525-44f8-82d8-544a9e16039a",
+ "metadata": {},
+ "source": [
+ "### Create instances of the models with common setup"
+ ]
+ },
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": null,
"id": "b33d3ccb",
"metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Instantiating AnalyticalSoln\n",
- "Instantiating RunPartMC\n",
- "Instantiating RunPySDM\n",
- "Instantiating NewModelRun\n",
- "Instantiating RunDropletsJL\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
"models = {\n",
- " # Create instances of the models with common setup\n",
" 'analytical': AnalyticalSoln(SETTINGS),\n",
" 'PartMC': RunPartMC(SETTINGS),\n",
" 'PySDM': RunPySDM(SETTINGS),\n",
@@ -581,19 +589,29 @@
"}\n",
"if shutil.which('julia') is not None: # pylint: disable=undefined-variable\n",
" models['Droplets.jl'] = RunDropletsJL(SETTINGS)\n",
+ "else:\n",
+ " warnings.warn('Julia not found, skipping Droplets.jl run')\n",
"output = {k: print(f\"Running {k}...\") or model() for k, model in models.items()}"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "c1d3a943-4523-4364-aa37-603dd2a45d6e",
+ "metadata": {},
+ "source": [
+ "### use open_atmos_jupyter_utils to create comparison animation"
+ ]
+ },
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": 15,
"id": "6cc84269",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
- "
"
+ "
"
],
"text/plain": [
""
@@ -605,12 +623,12 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "4a6734f7155f43aaae9abff70bb4b3cd",
+ "model_id": "afd169224d2540a0a170acb9ef676fac",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
- "HTML(value=\"./tmpcuc301a8.gif
\")"
+ "HTML(value=\"./tmpl0kmjlg7.gif
\")"
]
},
"metadata": {},
@@ -619,7 +637,7 @@
{
"data": {
"text/html": [
- "
"
+ "
"
],
"text/plain": [
""
@@ -631,12 +649,12 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "9a0c70e5a33a4ebba114a276d215b1f5",
+ "model_id": "04d5423b58cf434abd60acb4cb72a17d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
- "HTML(value=\"./tmpzvejmu2p.gif
\")"
+ "HTML(value=\"./tmpo_g26hgw.gif
\")"
]
},
"metadata": {},
@@ -651,7 +669,6 @@
"radius_bins = np.array(models['PartMC'].rad_grid.centers)\n",
"kilograms_to_grams = 1e3\n",
"\n",
- "\n",
"markers = {\n",
" 'PartMC':'o', \n",
" 'PySDM':'x',\n",
@@ -659,7 +676,6 @@
" '':'s' #NEW_MODEL\n",
"} \n",
"\n",
- "# use open_atmos_jupyter_utils to create comparison animation\n",
"class AnimFunc:\n",
" def __init__(self, binning_method):\n",
" self.binning_method = binning_method\n",
@@ -699,7 +715,7 @@
" if self.binning_method != 'Number Concentration (#/m^3/unit ln R)':\n",
" plt.ylim([0,2])\n",
" plt.xlim([SETTINGS.RADIUS_BIN_EDGES_M[0],SETTINGS.RADIUS_BIN_EDGES_M[-1]])\n",
- " plt.legend(loc='upper right')#, bbox_to_anchor=(1, 0.5))\n",
+ " plt.legend(loc='upper right')\n",
" plt.title(\"Time Evolution of Particle Size Distribution, t = \"\n",
" +f\"{frame*SETTINGS.PLOT_TIME_STEP_SEC//60:02d} min\")\n",
" return plt.gcf()\n",
@@ -711,15 +727,21 @@
" )"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "a5fe6e01-c736-45a7-87d1-436a72d53100",
+ "metadata": {},
+ "source": [
+ "### sanity check for conservation of mass"
+ ]
+ },
{
"cell_type": "code",
- "execution_count": 13,
+ "execution_count": 16,
"id": "0eaf456b",
"metadata": {},
"outputs": [],
"source": [
- "# sanity check for conservation of mass\n",
- "\n",
"for model in output:\n",
" if model == '':\n",
" continue\n",
@@ -732,8 +754,16 @@
" np.log(SETTINGS.RADIUS_BIN_EDGES_M[1:]) - np.log(SETTINGS.RADIUS_BIN_EDGES_M[:-1])\n",
" ),\n",
" significant=1.75\n",
- " )\n"
+ " )"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "fead341e-6092-428f-8dce-3b4660d04526",
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
@@ -752,7 +782,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.9.12"
+ "version": "3.9.2"
}
},
"nbformat": 4,
diff --git a/src/aero_data.hpp b/src/aero_data.hpp
index f830e928..4143959f 100644
--- a/src/aero_data.hpp
+++ b/src/aero_data.hpp
@@ -46,6 +46,7 @@ struct AeroData {
JSONResourceGuard guard(json);
f_aero_data_from_json(this->ptr.f_arg());
+ guard.check_parameters();
}
AeroData() :
diff --git a/src/aero_dist.hpp b/src/aero_dist.hpp
index b7e3b0c0..fe867561 100644
--- a/src/aero_dist.hpp
+++ b/src/aero_dist.hpp
@@ -54,6 +54,7 @@ struct AeroDist {
JSONResourceGuard guard(json, "", "mode_name", 1);
f_aero_dist_from_json(ptr.f_arg_non_const(), aero_data->ptr.f_arg_non_const());
+ guard.check_parameters();
}
AeroDist() :
diff --git a/src/aero_mode.hpp b/src/aero_mode.hpp
index e7576d87..4ed3d8d9 100644
--- a/src/aero_mode.hpp
+++ b/src/aero_mode.hpp
@@ -147,6 +147,7 @@ struct AeroMode {
check_mode_json(json.begin().value());
JSONResourceGuard guard(json, "", "mode_name");
f_aero_mode_from_json(ptr.f_arg_non_const(), aero_data.ptr.f_arg_non_const());
+ guard.check_parameters();
}
static void check_mode_json(const nlohmann::json &mode) {
diff --git a/src/env_state.hpp b/src/env_state.hpp
index 5a443cdc..990742d5 100644
--- a/src/env_state.hpp
+++ b/src/env_state.hpp
@@ -34,6 +34,7 @@ struct EnvState {
{
JSONResourceGuard guard(json);
f_env_state_from_json(this->ptr.f_arg());
+ guard.check_parameters();
}
EnvState() :
diff --git a/src/gas_data.hpp b/src/gas_data.hpp
index ecb14998..7bcd0103 100644
--- a/src/gas_data.hpp
+++ b/src/gas_data.hpp
@@ -39,6 +39,7 @@ struct GasData {
JSONResourceGuard guard(json_array);
f_gas_data_from_json(this->ptr.f_arg());
+ guard.check_parameters();
}
GasData() :
diff --git a/src/gas_state.hpp b/src/gas_state.hpp
index 050795b1..c6769ca6 100644
--- a/src/gas_state.hpp
+++ b/src/gas_state.hpp
@@ -125,5 +125,6 @@ struct GasState {
self.ptr.f_arg(),
self.gas_data->ptr.f_arg()
);
+ guard.check_parameters();
}
};
diff --git a/src/input_guard.hpp b/src/input_guard.hpp
new file mode 100644
index 00000000..9ac7b18f
--- /dev/null
+++ b/src/input_guard.hpp
@@ -0,0 +1,155 @@
+#include
+#include
+#include