{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Sea-Ice Model Package (SPyIce)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The SPyIce package is a software tool that enables 1D finite difference simulation for vertical transport equations. It specifically focuses on thermal diffusion with the influence of salinity and physical properties. The package utilizes the Thomas tridiagonal solver as the solver algorithm. With SPyIce, users can model and analyze the behavior of temperature, salinity, and other relevant variables in a vertical system. It provides a comprehensive framework for studying the thermal diffusion process and its interaction with salinity in various scenarios. Hydra is used to automate the simulation runs of the Sea-Ice Model. It is used to manage and run sea ice simulations, making it easier for users to explore different scenarios and optimize their models.\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": "### Example 1: Simple simulation without automation configuration" }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Import Packages" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-11T10:53:45.204092Z", "start_time": "2026-03-11T10:53:44.500043300Z" } }, "source": [ "# creates a OmegaConf object from a dictionary\n", "from pathlib import Path\n", "from omegaconf import OmegaConf\n", "\n", "from spyice.utils import create_output_directory\n", "from spyice.postprocess import Analysis, VisualiseModel\n", "from spyice.utils import ConfigSort\n", "from spyice.models import SeaIceModel\n", "from spyice.preprocess import PreProcess" ], "outputs": [], "execution_count": 1 }, { "metadata": {}, "cell_type": "markdown", "source": "#### Define Inputs and Project Output paths" }, { "metadata": {}, "cell_type": "markdown", "source": [ "##### Constants Configuration\n", "\n", "- `constants: dict[str]`\n", "Specifies the type of physical constants used by the model (e.g., `\"real\"` for real-world physical values or \"debug\" which assigns 0s and 1s).\n", "\n", "- `dt: dict[float]`\n", "Simulation time step size used for each iteration of the numerical model.\n", "\n", "- `iter_max: dict[int]`\n", "Maximum number of time iterations for simulation where total simulation time = iter_max*dt.\n", "\n", "- `dz: dict[float]`\n", "Vertical grid spacing defining the spatial resolution of the model domain.\n", "\n", "- `model: dict[bool | str]`\n", "Flags controlling which physical or biological equations are enabled in the simulation.\n", "\n", " - `is_diffusiononly_equation: bool` — Enables the heat diffusion-only transport equation.\n", " - `is_salinity_equation: bool` — Activates the salinity transport equation.\n", " - `is_radiation_equation: bool` — Includes the radiation/light transfer model.\n", " - `is_algae_equation: bool` — Enables the algae dynamics model.\n", " - `algae_model_BAL_type: str` — Specifies the BAL algae model variant (e.g., `\"all\"` for all processes).\n", "\n", "- `ICBC: dict[str | float]`\n", "Initial conditions (IC) and boundary conditions (BC) for the simulation.\n", "\n", " - `S_IC: str` — Initial salinity condition identifier (e.g., `\"S_34\"`).\n", " - `T_BC: float` — Temperature top/surface boundary condition value." ] }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-11T10:53:48.253892800Z", "start_time": "2026-03-11T10:53:48.233472500Z" } }, "cell_type": "code", "source": [ "# creates a OmegaConf object from a dictionary for fast testing only for the above parameters\n", "constants_dict = {\n", " \"constants\": {\"constants\": \"real\"},\n", " \"dt\": {\"dt\": 47},\n", " \"iter_max\": {\"iter_max\": 1500},\n", " \"dz\": {\"dz\": 0.01},\n", " \"model\": {\"is_diffusiononly_equation\": True, \"is_salinity_equation\": True, \"is_radiation_equation\": True, \"is_algae_equation\": True, \"algae_model_BAL_type\": \"all\"},\n", " \"ICBC\": {\"S_IC\": 'S_34', \"T_BC\": 265.0}\n", "}" ], "outputs": [], "execution_count": 2 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-11T11:13:13.221809Z", "start_time": "2026-03-11T11:13:13.199748200Z" } }, "cell_type": "code", "source": [ "config_raw = OmegaConf.create(constants_dict)\n", "config = ConfigSort.getconfig_dataclass(config_raw, config_type=\"jupyter\")\n", "\n", "# choose your output directory\n", "output_base_dir = Path(\"../example/output/without_hydra\")\n", "out_dir_final = create_output_directory(output_base_dir, \"S34\",\"2\", \"0.01\", \"47\", \"1500\", \"example\")" ], "outputs": [], "execution_count": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Preprocessing, Running and Analysis of Sea-Ice Model" ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-11T10:58:00.816250400Z", "start_time": "2026-03-11T10:57:42.562265600Z" } }, "source": [ "# preprocess the data\n", "preprocess_data, userinput_data = PreProcess.get_variables(config_raw, out_dir_final)\n", "results_data = SeaIceModel.get_results(preprocess_data, userinput_data)\n", "# Note: analysis data inputs should not be changed!\n", "analysis_data = Analysis.get_error_results(\n", " t_k_diff=results_data.t_k_diff,\n", " t_stefan_diff=results_data.t_stefan_diff,\n", " residual=results_data.residual_voller_all,\n", " temperature_mushy=results_data.t_k_iter_all,\n", " phi_mushy=results_data.all_phi_iter_all,\n", " salinity_mushy=results_data.s_k_iter_all,\n", " output_dir=out_dir_final,\n", " )" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Preprocessing...\n", "User Configuration Data Setup Complete...\n", "Geometry Data Setup Complete...\n", "Results Data Setup Complete...\n", "Time step set to: 47s\n", "Applied Initial & Boundary Conditions...\n", "Preprocessing done.\n", "Running model...\n", "Model run complete and Ready for Analysis.\n", "Running error analysis...\n", "Calculating errors...\n", "Residuals exported successfully.\n" ] }, { "data": { "text/plain": [ "
" ], "image/png": "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" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Visualization of Model with VisualiseModel " ] }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-11T10:58:06.489748100Z", "start_time": "2026-03-11T10:58:06.446521900Z" } }, "source": [ "model_visualization_object = VisualiseModel(\n", " user_input_dataclass=userinput_data,\n", " results_dataclass=results_data,\n", " error_analysis_dataclass=analysis_data,\n", ")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Visualisation object created...\n" ] } ], "execution_count": 13 }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-11T10:58:10.748169Z", "start_time": "2026-03-11T10:58:10.690637600Z" } }, "source": [ "# Plots the Temperature Difference between Analytical and Numerical Solutions\n", "model_visualization_object.plot_error_temp(100, norm=\"inf\", savefig=False)\n" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Plotting Temperature errors using inf norm...\n" ] } ], "execution_count": 14 }, { "cell_type": "code", "metadata": {}, "source": [ "# Plots the interface tracking over time for Analytical and Numerical Solutions\n", "model_visualization_object.plot_depth_over_time(savefig=True)\n" ], "outputs": [], "execution_count": null }, { "metadata": {}, "cell_type": "markdown", "source": "### Example 2: Simulation with Hydra hierarchial and automation configuration" }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-11T11:15:00.221841200Z", "start_time": "2026-03-11T11:15:00.096242100Z" } }, "source": [ "from pathlib import Path\n", "\n", "from hydra import (\n", " compose,\n", " initialize,\n", ")\n", "\n", "from spyice.main_process import MainProcess" ], "outputs": [], "execution_count": 16 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-11T11:15:02.187259900Z", "start_time": "2026-03-11T11:15:02.166054500Z" } }, "cell_type": "code", "source": [ "# choose your output directory\n", "output_base_dir = Path(\"../example/output/with_hydra\")" ], "outputs": [], "execution_count": 17 }, { "metadata": {}, "cell_type": "markdown", "source": [ "Model settings can be modified in the `example/conf` directory for:\n", "- constants\n", "- dt\n", "- dz\n", "- ICBC\n", "- model\n", "\n", "or in the `overrides` option during initialize as seen in the next step." ] }, { "cell_type": "markdown", "metadata": {}, "source": "To run the Sea-Ice Model using Hydra and the `MainProcess` script, users simply need to initialize Hydra, load the configuration file, specify any desired overrides, and then create an instance of the `MainProcess` class. The `run_model()` method is then called to execute the simulation. This streamlined process makes it simple for users to run the model with different configurations and analyze the results whose outputs are stored in **outputs** directory as ." }, { "cell_type": "code", "metadata": { "ExecuteTime": { "end_time": "2026-03-11T11:15:29.357380200Z", "start_time": "2026-03-11T11:15:04.576608300Z" } }, "source": [ "with initialize(version_base=None, config_path=\"conf\"):\n", " cfg = compose(\n", " config_name=\"config.yaml\",\n", " overrides=[\"iter_max=iter_max1500\", \"dt=dt47\", \"dz=dz0p01\"],\n", " )\n", " out_hydra_dir = Path(output_base_dir, \"with_hydra\")\n", " main = MainProcess(cfg, out_hydra_dir)\n", " main.run_model()" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Preprocessing...\n", "User Configuration Data Setup Complete...\n", "Geometry Data Setup Complete...\n", "Results Data Setup Complete...\n", "Time step set to: 47s\n", "Applied Initial & Boundary Conditions...\n", "Preprocessing done.\n", "Running model...\n", "Model run complete and Ready for Analysis.\n", "Running error analysis...\n", "Calculating errors...\n", "Residuals exported successfully.\n", "Postprocessing...\n", "Visualisation object created...\n", "Plotting Temperature heatmap...\n", "Plotting Liquid-Fraction heatmap...\n", "Postprocessing done.\n" ] }, { "data": { "text/plain": [ "
" ], "image/png": "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" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 18 } ], "metadata": { "kernelspec": { "display_name": "spyice", "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.11.9" } }, "nbformat": 4, "nbformat_minor": 2 }