Skip to content

Commit

Permalink
Reduce linker memory to reduce false bubble connections. Produce a pr…
Browse files Browse the repository at this point in the history
…oof-of-concept correlation fit to own data.
  • Loading branch information
blakeNaccarato committed Oct 1, 2024
1 parent b09ccdc commit 4456a5f
Show file tree
Hide file tree
Showing 15 changed files with 498 additions and 420 deletions.
282 changes: 154 additions & 128 deletions docs/notebooks/e230920_fit_tracks.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
":::\n",
"::::\n",
"\n",
"# Fit tracks\n",
"\n",
"Compare experimental bubble histories to bubble history correlations. Bubble detection and linking performed by Trackpy, an implementation of the Crocker-Grier algorithm {cite}`allanTrackpy2018,crockerMethodsDigitalVideo1996`.\n"
"# Fit tracks"
]
},
{
Expand All @@ -29,47 +27,64 @@
},
"outputs": [],
"source": [
"from dev.docs.nbs import init\n",
"from __future__ import annotations\n",
"\n",
"paths = init()\n",
"from typing import Any\n",
"from warnings import catch_warnings\n",
"\n",
"from boilercore.fits import Fit, fit_from_params, get_guesses\n",
"from boilercv_pipeline.models.path import get_datetime\n",
"from boilercv_pipeline.stages import get_thermal_data\n",
"from boilercv_pipeline.stages.find_tracks import FindTracks as Params\n",
"from dev.docs.nbs import init\n",
"from devtools import pprint\n",
"from more_itertools import one\n",
"from numpy import diagonal, full, inf, isinf, nan, sqrt, where\n",
"from pandas import concat, read_hdf\n",
"from scipy.optimize import OptimizeWarning, curve_fit\n",
"from scipy.stats import t\n",
"\n",
"from boilercv.dimensionless_params import jakob, prandtl"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"hide-input",
"hide-output"
]
},
"outputs": [],
"source": [
"params = Params(context=init(), only_sample=True)\n",
"params.set_display_options()\n",
"C = params.cols\n",
"\n",
"from boilercore.fits import Fit, fit_from_params\n",
"from boilercv_pipeline.experiments.e230920_subcool import MERGED_TRACKS, THERMAL_DATA\n",
"from dev.docs.nbs import HIDE, set_display_options\n",
"from matplotlib.figure import Figure\n",
"from matplotlib.pyplot import subplots\n",
"from numpy import inf\n",
"from pandas import read_hdf, to_datetime\n",
"from seaborn import color_palette, lineplot, move_legend, scatterplot\n",
"thermal = read_hdf(params.deps.thermal)\n",
"TC = get_thermal_data.Cols()\n",
"\n",
"from boilercv.correlations import SYMBOL_LABELS\n",
"from boilercv.dimensionless_params import jakob, prandtl\n",
"all_tracks = list(one(params.dfs).parent.iterdir())\n",
"times = [get_datetime(p.stem) for p in all_tracks]\n",
"\n",
"FIGURES: list[Figure] = []\n",
"# Physical parameters\n",
"LATENT_HEAT_OF_VAPORIZATION = 2.23e6 # J/kg\n",
"LIQUID_DENSITY = 960 # kg/m^3\n",
"LIQUID_DYNAMIC_VISCOSITY = 2.88e-4 # Pa-s\n",
"LIQUID_ISOBARIC_SPECIFIC_HEAT = 4213 # J/kg-K\n",
"LIQUID_THERMAL_CONDUCTIVITY = 0.676 # W/m-K\n",
"VAPOR_DENSITY = 0.804 # kg/m^3\n",
"\n",
"MAX_REYNOLDS = 1500\n",
"MAX_NUSSELT = 50000\n",
"\n",
"SCALE = 1.3\n",
"\"\"\"Plot scale.\"\"\"\n",
"SIZE = 20 * SCALE\n",
"\"\"\"Size of the tracks.\"\"\"\n",
"FONT_SCALE = SCALE\n",
"\"\"\"Font scale for plotting.\"\"\"\n",
"WIDTH_SCALE = 2.00\n",
"\"\"\"Width scale for plotting.\"\"\"\n",
"HEIGHT_SCALE = 1.30\n",
"\"\"\"Height scale for plotting.\"\"\"\n",
"# Plotting\n",
"MAX_FOURIER = 0.005\n",
"\"\"\"Maximum Fourier number to plot.\"\"\"\n",
"MAX_BETA = 1.00\n",
"\"\"\"Maximum dimensionless bubble diameter to plot.\"\"\"\n",
"MAX_NUSSELT = 1000\n",
"\"\"\"Maximum Nusselt number to plot.\"\"\"\n",
"\n",
"\n",
"HIDE"
"pprint(params)"
]
},
{
Expand All @@ -82,34 +97,48 @@
},
"outputs": [],
"source": [
"set_display_options(FONT_SCALE)\n",
"thermal_data = read_hdf(THERMAL_DATA)\n",
"# C_1 = 1.46\n",
"C_2 = 0.61\n",
"C_3 = 0.33\n",
"\n",
"tracks = (\n",
" read_hdf(MERGED_TRACKS)\n",
" .assign(**{\"datetime\": lambda df: to_datetime(df[\"datetime\"])})\n",
" .set_index(\"datetime\")\n",
" .assign(**{\"Subcooling (K)\": lambda df: thermal_data[\"subcool\"]})\n",
" .reset_index(drop=True)\n",
" concat(\n",
" read_hdf(p, key=\"dst\").assign(**{TC.time(): time})\n",
" for p, time in zip(all_tracks, times, strict=True)\n",
" )\n",
" # .pipe(\n",
" # lambda df: df[\n",
" # (df[C.bub_beta()] > 0)\n",
" # & (df[C.bub_beta()] < MAX_BETA)\n",
" # & (df[C.bub_nusselt()] > 0)\n",
" # & (df[C.bub_nusselt()] < MAX_NUSSELT)\n",
" # & (df[C.bub_fourier()] < MAX_FOURIER)\n",
" # ]\n",
" # )\n",
" .set_index(TC.time())\n",
" .assign(**{\n",
" \"Ja\": lambda df: jakob(\n",
" TC.subcool(): thermal.set_index(TC.time()).loc[times, TC.subcool()], # pyright: ignore[reportArgumentType, reportCallIssue]\n",
" \"jakob\": lambda df: jakob(\n",
" liquid_density=LIQUID_DENSITY,\n",
" vapor_density=VAPOR_DENSITY,\n",
" liquid_isobaric_specific_heat=LIQUID_ISOBARIC_SPECIFIC_HEAT,\n",
" subcooling=df[\"Subcooling (K)\"],\n",
" subcooling=df[TC.subcool()],\n",
" latent_heat_of_vaporization=LATENT_HEAT_OF_VAPORIZATION,\n",
" )\n",
" ),\n",
" })\n",
").query(\"diameter_rate_of_change < 0\")\n",
"constants = {\n",
" \"Pr\": prandtl(\n",
" dynamic_viscosity=LIQUID_DYNAMIC_VISCOSITY,\n",
" isobaric_specific_heat=LIQUID_ISOBARIC_SPECIFIC_HEAT,\n",
" thermal_conductivity=LIQUID_THERMAL_CONDUCTIVITY,\n",
" ),\n",
" \"Ja\": tracks[\"Ja\"].mean(),\n",
"}\n",
" .reset_index()\n",
")\n",
"Pr = prandtl(\n",
" dynamic_viscosity=LIQUID_DYNAMIC_VISCOSITY,\n",
" isobaric_specific_heat=LIQUID_ISOBARIC_SPECIFIC_HEAT,\n",
" thermal_conductivity=LIQUID_THERMAL_CONDUCTIVITY,\n",
")\n",
"Ja = tracks[\"jakob\"].median()\n",
"Re_b0 = tracks[C.bub_reynolds0()].median()\n",
"\n",
"\n",
"tracks"
"def Nu(Re_b, C_1, C_4): # noqa: N803, D103, N802\n",
" return C_1 * Re_b**C_2 * Pr**C_3 * Ja**C_4"
]
},
{
Expand All @@ -122,70 +151,58 @@
},
"outputs": [],
"source": [
"def nusselt_model(Re_b, C_1, C_2, C_3, C_4): # noqa: N803, D103\n",
" return C_1 * Re_b**C_2 * constants[\"Pr\"] ** C_3 * constants[\"Ja\"] ** C_4\n",
"def fit(\n",
" model: Any,\n",
" free_params: list[str],\n",
" initial_values: dict[str, float],\n",
" x: Any,\n",
" y: Any,\n",
" n: int,\n",
") -> tuple[dict[str, float], dict[str, float]]:\n",
" \"\"\"Get fits and errors for project model.\"\"\"\n",
" with catch_warnings():\n",
" try:\n",
" fits, pcov = curve_fit(\n",
" f=model, p0=get_guesses(free_params, initial_values), xdata=x, ydata=y\n",
" )\n",
" except (RuntimeError, OptimizeWarning):\n",
" dim = len(free_params)\n",
" fits = full(dim, nan)\n",
" pcov = full((dim, dim), nan)\n",
" # Compute confidence interval\n",
" standard_errors = sqrt(diagonal(pcov))\n",
" errors = standard_errors * t.interval(0.95, n)[1]\n",
" # Catching `OptimizeWarning` should be enough, but let's explicitly check for inf\n",
" fits = where(isinf(errors), nan, fits)\n",
" errors = where(isinf(errors), nan, errors)\n",
" return (\n",
" dict(zip(free_params, fits, strict=True)),\n",
" dict(zip([f\"{p}_err\" for p in free_params], errors, strict=True)),\n",
" )\n",
"\n",
"\n",
"fits, errors = fit_from_params(\n",
" model=nusselt_model,\n",
" params=Fit(\n",
" independent_params=[\"Re_b\"],\n",
" free_params=(params := [\"C_1\", \"C_2\", \"C_3\", \"C_4\"]),\n",
" fixed_params=[],\n",
" bounds=dict.fromkeys(params, (0, inf)),\n",
" values=dict.fromkeys(params, 1),\n",
" ),\n",
" x=tracks[\"Re_b\"].values,\n",
" y=tracks[\"Nu_c\"].values,\n",
")\n",
"\n",
"fits"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"errors"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"figure, ax = subplots()\n",
"FIGURES.append(figure)\n",
"ax.set_xlim(0, MAX_REYNOLDS)\n",
"ax.set_ylim(0, MAX_NUSSELT)\n",
"scatterplot(\n",
" data=tracks.rename(columns=SYMBOL_LABELS),\n",
" ax=ax,\n",
" x=\"Bubble Reynolds number\",\n",
" y=\"Nusselt number\",\n",
" hue=\"Subcooling (K)\",\n",
" palette=color_palette(\"flare\", as_cmap=True),\n",
" s=SIZE,\n",
")\n",
"data = (\n",
" tracks.assign(**{\"Model\": nusselt_model(tracks[\"Re_b\"], **fits)})\n",
" .rename(columns=SYMBOL_LABELS)\n",
" .set_index(\"Bubble Reynolds number\")[[\"Model\"]]\n",
"fits, errors = fit(\n",
" model=Nu,\n",
" free_params=([\"C_1\", \"C_4\"]),\n",
" initial_values={\"C_1\": 1, \"C_4\": 1.0},\n",
" x=tracks[C.bub_reynolds()].values,\n",
" y=tracks[C.bub_nusselt()].values,\n",
" n=len(tracks),\n",
")\n",
"lineplot(ax=ax, data=data, legend=False)\n",
"move_legend(ax, \"upper right\")\n",
"HIDE"
"display(\n",
" {\n",
" # \"C_1\": C_1,\n",
" \"C_2\": C_2,\n",
" \"C_3\": C_3,\n",
" **fits,\n",
" \"C_5\": 2 * fits[\"C_1\"],\n",
" \"C_6\": 1 + fits[\"C_4\"],\n",
" # \"C_5\": 2 * C_1 * (2 - C_2),\n",
" # \"C_6\": 1 + fits[\"C_4\"],\n",
" # \"C_7\": 1 / (2 - C_2),\n",
" },\n",
" errors,\n",
")"
]
},
{
Expand All @@ -198,22 +215,31 @@
},
"outputs": [],
"source": [
"figure, ax = subplots()\n",
"FIGURES.append(figure)\n",
"scatterplot(\n",
" data=tracks.rename(columns=SYMBOL_LABELS),\n",
" ax=ax,\n",
" x=\"Bubble Reynolds number\",\n",
" y=\"Nusselt number\",\n",
" hue=\"Subcooling (K)\",\n",
" palette=color_palette(\"flare\", as_cmap=True),\n",
" s=SIZE,\n",
"fits, errors = fit_from_params(\n",
" model=Nu,\n",
" params=Fit(\n",
" independent_params=[\"Re_b\"],\n",
" free_params=(nusselt_params := [\"C_1\", \"C_4\"]),\n",
" fixed_params=[],\n",
" bounds={\"C_1\": (-inf, inf), \"C_4\": (-inf, inf)},\n",
" values={\"C_1\": 1.0, \"C_4\": 1.0},\n",
" ),\n",
" x=tracks[C.bub_reynolds()].values,\n",
" y=tracks[C.bub_nusselt()].values,\n",
")\n",
"ax.set(xscale=\"log\", yscale=\"log\")\n",
"ax.set_xlim(1e-14, 1e14)\n",
"ax.set_ylim(1e-17, 1e6)\n",
"move_legend(ax, \"upper right\")\n",
"HIDE"
"display(\n",
" {\n",
" \"C_2\": C_2,\n",
" \"C_3\": C_3,\n",
" **fits,\n",
" \"C_5\": 2 * fits[\"C_1\"],\n",
" \"C_6\": 1 + fits[\"C_4\"],\n",
" # \"C_5\": 2 * C_1 * (2 - C_2),\n",
" # \"C_6\": (1 + fits[\"C_4\"]),\n",
" # \"C_7\": (1 / (2 - C_2)),\n",
" },\n",
" errors,\n",
")"
]
}
],
Expand All @@ -233,7 +259,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
"version": "3.11.10"
},
"papermill": {
"parameters": {
Expand Down
3 changes: 2 additions & 1 deletion docs/notebooks/find_objects.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
"MODE = get_mode()\n",
"\"\"\"Notebook execution mode.\"\"\"\n",
"PREVIEW_FRAME_COUNT = 50\n",
"\"\"\"Number of preview frames.\"\"\""
"\"\"\"Number of preview frames.\"\"\"\n",
"Params.hide()"
]
},
{
Expand Down
Loading

0 comments on commit 4456a5f

Please sign in to comment.