rustmatrix 2.1.1

Rust-backed T-matrix scattering for nonspherical particles (port of pytmatrix)
Documentation
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tutorial 01 \u2014 A dielectric sphere at X-band, checked against Mie\n",
    "\n",
    "A T-matrix solver for nonspherical particles must reduce to classical\n",
    "Mie theory in the `axis_ratio = 1` limit. That reduction is the\n",
    "simplest end-to-end check we can do. This tutorial builds a 1 mm\n",
    "water sphere at X-band, computes its scattering and extinction\n",
    "cross-sections via the T-matrix path, and compares against the\n",
    "closed-form Mie expressions shipped with rustmatrix.\n"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from rustmatrix import Scatterer, mie_qsca, mie_qext, scatter\n",
    "from rustmatrix.tmatrix_aux import geom_horiz_back, wl_X\n",
    "from rustmatrix.refractive import m_w_10C\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build a sphere scatterer at X-band\n"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "radius_mm = 1.0\n",
    "wavelength_mm = wl_X\n",
    "m = m_w_10C[wl_X]\n",
    "\n",
    "s = Scatterer(radius=radius_mm, wavelength=wavelength_mm, m=m,\n",
    "              axis_ratio=1.0, ddelt=1e-4, ndgs=2)\n",
    "s.set_geometry(geom_horiz_back)\n",
    "S, Z = s.get_SZ()\n",
    "S\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cross-sections \u2014 T-matrix vs Mie\n"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "size_param = 2.0 * np.pi * radius_mm / wavelength_mm\n",
    "sigma_sca_tm = scatter.sca_xsect(s, h_pol=True)\n",
    "sigma_ext_tm = scatter.ext_xsect(s, h_pol=True)\n",
    "\n",
    "geom = np.pi * radius_mm ** 2\n",
    "sigma_sca_mie = mie_qsca(size_param, m.real, m.imag) * geom\n",
    "sigma_ext_mie = mie_qext(size_param, m.real, m.imag) * geom\n",
    "\n",
    "print(f'rel err \u03c3_sca = {abs(sigma_sca_tm-sigma_sca_mie)/sigma_sca_mie:.2e}')\n",
    "print(f'rel err \u03c3_ext = {abs(sigma_ext_tm-sigma_ext_mie)/sigma_ext_mie:.2e}')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Q_sca and Q_ext across a size-parameter sweep\n",
    "\n",
    "Plotting both curves side by side makes the Mie ripple pattern\n",
    "visible and confirms that the T-matrix follows it point-for-point.\n"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "xs = np.linspace(0.1, 10.0, 40)\n",
    "q_sca_mie = np.array([mie_qsca(x, m.real, m.imag) for x in xs])\n",
    "q_ext_mie = np.array([mie_qext(x, m.real, m.imag) for x in xs])\n",
    "q_sca_tm = np.empty_like(xs)\n",
    "q_ext_tm = np.empty_like(xs)\n",
    "for i, x in enumerate(xs):\n",
    "    r = x * wavelength_mm / (2.0 * np.pi)\n",
    "    si = Scatterer(radius=r, wavelength=wavelength_mm, m=m,\n",
    "                   axis_ratio=1.0, ddelt=1e-4, ndgs=2)\n",
    "    si.set_geometry(geom_horiz_back)\n",
    "    g = np.pi * r ** 2\n",
    "    q_sca_tm[i] = scatter.sca_xsect(si) / g\n",
    "    q_ext_tm[i] = scatter.ext_xsect(si) / g\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(7, 4))\n",
    "ax.plot(xs, q_sca_mie, 'k-', label='Q_sca (Mie)')\n",
    "ax.plot(xs, q_ext_mie, 'k--', label='Q_ext (Mie)')\n",
    "ax.plot(xs, q_sca_tm, 'C1o', markersize=4, label='Q_sca (T-matrix)')\n",
    "ax.plot(xs, q_ext_tm, 'C2s', markersize=4, label='Q_ext (T-matrix)')\n",
    "ax.set_xlabel('size parameter  x = 2\u03c0r/\u03bb')\n",
    "ax.set_ylabel('efficiency')\n",
    "ax.legend()\n",
    "ax.grid(True, alpha=0.3)\n",
    "fig.tight_layout();\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}