{
    "cells": [
        {
            "cell_type": "markdown",
            "id": "55d0cc9d",
            "metadata": {},
            "source": [
                "# **Directed percolation in Rust-Python**\n",
                "\n",
                "Demo simulation of directed percolation on a 1d lattice."
            ]
        },
        {
            "cell_type": "markdown",
            "id": "47566d43",
            "metadata": {},
            "source": [
                "<hr>\n",
                "\n",
                "## Preliminaries"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 1,
            "id": "b8fa3294",
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/plain": [
                            "'2026.3.22'"
                        ]
                    },
                    "execution_count": 1,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "from essentials import *\n",
                "dprs.__version__"
            ]
        },
        {
            "cell_type": "markdown",
            "id": "a9e3b046",
            "metadata": {},
            "source": [
                "<hr>\n",
                "\n",
                "## Parameters"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 2,
            "id": "66226d2b",
            "metadata": {},
            "outputs": [],
            "source": [
                "class Parameters:\n",
                "    dim = sim.Dimension.D1\n",
                "    n_x: int = 10_000\n",
                "    n_y: int = 1\n",
                "    n_z: int = 1\n",
                "    p: float = 0.538910\n",
                "    p0: float = 0.99\n",
                "    seed: int = 5\n",
                "    n_iterations: int = 1000\n",
                "    sample_period: int  = 0\n",
                "    axis_topology_x = sim.Topology.Periodic\n",
                "    axis_topology_y = sim.Topology.Unspecified\n",
                "    axis_topology_z = sim.Topology.Unspecified\n",
                "    axis_bcs_x = (sim.BoundaryCondition.Floating, sim.BoundaryCondition.Floating)\n",
                "    axis_bcs_y = (sim.BoundaryCondition.Unspecified, sim.BoundaryCondition.Unspecified)\n",
                "    axis_bcs_z = (sim.BoundaryCondition.Unspecified, sim.BoundaryCondition.Unspecified)\n",
                "    axis_bc_values_x = (DUAL.OCCUPIED.state, DUAL.OCCUPIED.state)\n",
                "    axis_bc_values_y = (DUAL.EMPTY.state, DUAL.EMPTY.state)\n",
                "    axis_bc_values_z = (DUAL.EMPTY.state, DUAL.EMPTY.state)\n",
                "    do_edge_buffering: bool = True\n",
                "    processing = sim.Processing.Parallel\n",
                "    n_threads: int = 16\n",
                "parameters = Parameters()\n",
                "# Just in case we forget to update sample_period to match n_iterations\n",
                "if parameters.sample_period > parameters.n_iterations:\n",
                "    parameters.sample_period = parameters.n_iterations"
            ]
        },
        {
            "cell_type": "markdown",
            "id": "04e55881",
            "metadata": {},
            "source": [
                "<hr>\n",
                "\n",
                "## Simulation"
            ]
        },
        {
            "cell_type": "markdown",
            "id": "20ee9b5b",
            "metadata": {},
            "source": [
                "Execute the Rust-coded sim (for small grids, parallelization can actually slow down the processing):"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 3,
            "id": "1953de72",
            "metadata": {},
            "outputs": [],
            "source": [
                "n_lattices: int\n",
                "raw_lattices: list[list[bool]] \n",
                "raw_tracking: list[list, list]\n",
                "t_run_time: float"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 4,
            "id": "df8648d5",
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "\n",
                        "Dimension:   D1\n",
                        "Grid shape:  (10000, 1, 1)\n",
                        "Probability: 0.53891\n",
                        "Prob @t=0:   0.99\n",
                        "Random seed: 5\n",
                        "Iterations:  1000\n",
                        "Sampling:    0\n",
                        "Topology x:  Periodic\n",
                        "Topology y:  Unspecified\n",
                        "Topology z:  Unspecified\n",
                        "Axis BCs x:  (Floating, Floating)\n",
                        "Axis BCs y:  (Unspecified, Unspecified)\n",
                        "Axis BCs z:  (Unspecified, Unspecified)\n",
                        "BC values x: (true, true)\n",
                        "BC values y: (false, false)\n",
                        "BC values z: (false, false)\n",
                        "Edge buffer: true\n",
                        "Processing:  Parallel\n",
                        "Num threads: 16\n",
                        "\n",
                        "\n",
                        "Simulation run time (parallel processing): 0.039s\n"
                    ]
                }
            ],
            "source": [
                "(n_lattices, raw_lattices, raw_tracking, t_run_time)= sim.dk(parameters)"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 5,
            "id": "ff3ee1ca",
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "Total number of lattice time slices = 0\n",
                        "\n"
                    ]
                }
            ],
            "source": [
                "print(f\"Total number of lattice time slices = {n_lattices}\\n\")"
            ]
        },
        {
            "cell_type": "markdown",
            "id": "5ed70246",
            "metadata": {},
            "source": [
                "<hr>\n",
                "\n",
                "## Post-processing"
            ]
        },
        {
            "cell_type": "markdown",
            "id": "a687aca4",
            "metadata": {},
            "source": [
                "The function `sim.dk` returns a subset of the time-series of lattices generated by the simulation, with subsetting given by the `sample_rate` parameter, such that the total number provided is `n_lattices`. Each lattice is returned in flattened form as a 1d list, with all of them concatenated into one long 1d list."
            ]
        },
        {
            "cell_type": "markdown",
            "id": "ec37d47b",
            "metadata": {},
            "source": [
                "Tracking data, which for now is the vector pair (t; mean ρ):"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 6,
            "id": "0cd39968",
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/plain": [
                            "(2, 1001)"
                        ]
                    },
                    "execution_count": 6,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "tracking: NDArray = np.array(raw_tracking, dtype=np.float64,) \n",
                "tracking.shape"
            ]
        },
        {
            "cell_type": "markdown",
            "id": "37843af4",
            "metadata": {},
            "source": [
                "<hr>\n",
                "\n",
                "## Visualization"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 7,
            "id": "2a752a13",
            "metadata": {},
            "outputs": [],
            "source": [
                "viz = Viz(dpi=100)\n",
                "name: str"
            ]
        },
        {
            "cell_type": "markdown",
            "id": "fac0a8e0",
            "metadata": {},
            "source": [
                "See Henkel et al (2008), tables 4.1 and 4.3: the decay rate of the mean order parameter (mean occupancy) $\\overline\\rho$ should decay with time as\n",
                "$$\n",
                "    \\rho(t) \\sim t^{-\\delta}\n",
                "$$\n",
                "where in $d=1$ we should find $\\delta \\approx 0.1594646$ in 1d. \n",
                "\n",
                "Here I have heuristically tuned $p$ to\n",
                "$$\n",
                "    p = p_c? = \\,\\,0.538910\n",
                "$$\n",
                "which is close to the typically expected $\\sim \\!\\!1/2$."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 8,
            "id": "0981a0b0",
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "ρmean_p0p538910_s5_nx10000\n"
                    ]
                },
                {
                    "data": {
                        "image/png": "[encoded data, 110368 characters]",
                        "text/plain": [
                            "<Figure size 600x400 with 1 Axes>"
                        ]
                    },
                    "metadata": {
                        "image/png": {
                            "height": 400,
                            "width": 578
                        }
                    },
                    "output_type": "display_data"
                }
            ],
            "source": [
                "δ = 0.1594646\n",
                "ρ_mean_ref = 0.563\n",
                "\n",
                "name = make_name(parameters, \"ρmean\", None, )\n",
                "print(name)\n",
                "viz.plot_ρmean(\n",
                "    name,\n",
                "    make_title(parameters, None),\n",
                "    tracking,\n",
                "    δ, \n",
                "    ρ_mean_ref,\n",
                "    fig_size=(6,4,),\n",
                "    i_offset=1,\n",
                "    do_ref_curve=True,\n",
                ")\n",
                "plt.show()"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 9,
            "id": "a00db691",
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "Estimated t-decay exponent:  δ = -0.220\n"
                    ]
                }
            ],
            "source": [
                "i_offset: int = parameters.n_iterations//3\n",
                "t: NDArray = tracking[0][i_offset:]\n",
                "ρ_mean: NDArray = tracking[1][i_offset:]\n",
                "(exponent, scale, r_value, p_value, std_err) \\\n",
                "    = linregress(np.log(t), np.log(ρ_mean))\n",
                "\n",
                "print(rf\"Estimated t-decay exponent:  δ = {exponent:0.3f}\")"
            ]
        },
        {
            "cell_type": "markdown",
            "id": "46b9e6c9",
            "metadata": {},
            "source": [
                "<hr>\n",
                "\n",
                "## Export"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 10,
            "id": "77f7dc1f",
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/plain": [
                            "'././plots/dp1d'"
                        ]
                    },
                    "execution_count": 10,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "plots_dir: str = create_directories((os.path.curdir,\"plots\",), \"dp1d\")\n",
                "export_plots(\n",
                "    viz.fdict,\n",
                "    plots_dir,\n",
                "    \"PNG\",\n",
                "    suffix=\"\",\n",
                "    dpi=150,\n",
                ")"
            ]
        }
    ],
    "metadata": {
        "kernelspec": {
            "display_name": "DPRS (3.14.3)",
            "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.14.3"
        }
    },
    "nbformat": 4,
    "nbformat_minor": 5
}
