{ "cells": [ { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "view-in-github" }, "source": [ "\"Open" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Time evolution of a Gaussian wavepacket\n", "[Prof. Jay Foley, University of North Carolina Charlotte](https://foleylab.github.io/)\n", "\n", "#### Objectives\n", "- To demonstrate the expansion of a Gaussian wavepacket as a superposition of particle-in-a-box energy eigenstates\n", "- To demonstrate the time-dependence of a Gaussian wavepacket traveling between two infinitely tall potential walls\n", "- To calculate the momentum uncertainty of the Gaussian wavepacket as a function of time\n", "\n", "#### Learning Outcomes\n", "By the end of this workbook, students should be able to\n", "- Expand an arbitrary wavefunction in the energy eigenstate basis, and specifically apply this to the expansion of a Gaussian wavepacket in the basis of the particle-in-a-box energy eigenstates\n", "- Utilize the `trapz` function of `numpy` to perform numeric integration\n", "- Use the known time dependence of energy eigenstates of the particle-in-a-box to simulate the time evolution of the Gaussian wavepacket travelling between two infinitely tall ptential walls\n", "- Use the capabilities of `matplotlib` to animate the motion of the Gaussian wavepacket\n", "- Compute time-dependent expectation values of the Gaussian wavepacket, and specifically track the momentum uncertainty of this state as a function of time." ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "DqCDR6mqeCqx" }, "source": [ "#### Summary\n", "We will demonstrate the time-dependence of an electron initially described by a Gaussian wavepacket that is travelling between two infinitely tall potential walls located at $x=0$ and $x = L$. The initial state of this wavepacket will be given by\n", "\\begin{equation}\n", "\\Psi(x,t_0) = \\frac{1}{\\sigma \\sqrt(2\\pi)} {\\rm exp}\\left(\\frac{-1}{2}\\left(\\frac{x-x_0}{\\sigma}\\right)^2\\right) {\\rm exp}(i k_0 x). \\tag{1}\n", "\\end{equation}\n", "Such a wavefunction describes a particle initially with a mean momentum and position of $\\hbar k_0$ and $x_0$, respectively, and $\\sigma$ relates to the spread (or position uncertainty)\n", "of the particle. In the code that follows, we will have $x_0 = 200$, $k_0 = 0.4$, and $\\sigma = 15$ atomic units. We will specify that the location of the left-most infinite potential is at $L = 500$ atomic units. We will use the fact that we can we can expand this wavefunction in any complete basis, and we will use the basis of the energy eigenfunctions of the particle in a box with $L = 500$ atomic units. \n", "\n", "Hence, we will expand the wavefunction as follows:\n", "\\begin{equation}\n", "\\Psi(x,t) = \\sum_{n=1}^N c_n \\sqrt{\\frac{2}{L}} {\\rm sin}\\left( \\frac{n \\pi x}{L} \\right)\n", "{\\rm exp}\\left(-\\frac{i E_n t}{\\hbar}\\right), \\tag{2}\n", "\\end{equation}\n", "where we have used the known time-dependence of each energy eigenstate. The energy eigenvalues have the form\n", "\\begin{equation}\n", "E_n = \\frac{n^2 \\pi^2 \\hbar^2}{2 m L^2}. \\tag{3}\n", "\\end{equation}\n", "Since we are working in atomic units, $\\hbar$ and $m$ will have the value of 1.\n", "\n", "The coefficients for the above expansion can be determined simply by\n", "\\begin{equation}\n", "c_n = \\sqrt{\\frac{2}{500}} \\int_0^{500} {\\rm sin}\\left(\\frac{n \\pi x}{500}\\right) \\cdot \\Psi(x,t_0) \\: dx \\tag{4}\n", "\\end{equation}\n", "where we have set $L = 500$. We will use the `numpy` function `trapz(fx, x)` to perform a trapezoid rule approximation to \n", "this integral." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step 0: Import libraries and initialize a plot object for the animation" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "from matplotlib import animation, rc\n", "from IPython.display import HTML\n", "\n", "\n", "# First set up the figure, the axis, and the plot element we want to animate\n", "fig, ax = plt.subplots()\n", "plt.close()\n", "\n", "### parameters for the gaussian wavepacket and the PIB functions\n", "x0 = 200\n", "sig = 15\n", "k0 = 0.4\n", "L = 500\n", "\n", "### grid of x values for the functions\n", "x = np.linspace(0,500,500)\n", "\n", "### parameters for plot\n", "ax.set_xlim((0, L))\n", "ax.set_ylim((-0.03, 0.03))\n", "\n", "line, = ax.plot([], [], lw=2)\n", "\n", "# initialization function: plot the background of each frame\n", "def init():\n", " line.set_data([], [])\n", " return (line,)" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "xW874_pZD6eg" }, "source": [ "#### Step 1: Define helper functions that will compute the PIB basis functions and energy eigenvalues\n", "It will be helpful to have helper functions that will evaluate the energy eigenfunctions and eigenvalues of the \n", "particle in a box given the quantum number $n$, the length of the box $L$, and the grid of $x$ values for the eigenfunction." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def energy_eigenvalue(n, L):\n", " \"\"\" Helper function to take the quantum number n of the particle in a box and the length \n", " of the box L and return the energy eigenvalue in atomic units. This assumes the mass of the particle\n", " is 1 in atomic units (i.e. it assumes the particle is an electron).\n", " The length should be in atomic units.\n", " \n", " Arguments\n", " ---------\n", " n : int\n", " the quantum state of the particle in a box\n", " \n", " L : float\n", " the length of the box in atomic units\n", " \"\"\"\n", " m = 1 \n", " return n ** 2 * np.pi ** 2 / ( 2 * m * L ** 2)\n", "\n", "def energy_eigenfunction_phase(n, L, t):\n", " \"\"\" Helper function to take the quantum number n of the particle in a box and the length \n", " of the box L, and the time value and return the time-dependent phase. This assumes the mass of the particle\n", " is 1 in atomic units (i.e. it assumes the particle is an electron).\n", " The length and time should be in atomic units.\n", " \n", " Arguments\n", " ---------\n", " n : int\n", " the quantum state of the particle in a box\n", " \n", " L : float\n", " the length of the box in atomic units\n", " \n", " t : float\n", " the time in atomic units\n", " \"\"\"\n", " ci = 0+1j\n", " En = energy_eigenvalue(n, L)\n", " return np.exp(-ci * En * t)\n", " \n", "\n", "def energy_eigenfunction(n, L, x):\n", " \"\"\" Helper function to take the quantum number n of the particle in a box, the length \n", " of the box L, and x-coordinate value(s) (single value or list) and return the corresponding\n", " energy eigenstate value(s) of the ordinary particle in a box. L and x should be in atomic units,\n", " and the maximum value of x should be L.\n", " \n", " Arguments\n", " ---------\n", " n : int\n", " the quantum state of the particle in a box \n", " L : float\n", " the length of the box in atomic units\n", " x : float (or numpy array of floats)\n", " the position variable for the energy eigenstate in atomic units\n", " \"\"\"\n", " return np.sqrt(2 / L) * np.sin(n * np.pi * x / L)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Step 2: Define a helper function that will compute values of the Gaussian wavepacket \n", "We will define a function to take the $\\sigma$, $x_0$, and $k_0$ parameters and $x$ value(s) that define Eq. (1) and return $\\Psi(x,t_0)$." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def gaussian_wavepacket(x0, sig, k0, x):\n", " \"\"\" Helper function to take the the spread (sig), mean wavenumber (k0), mean position value (x0) \n", " and grid of x-values (x) and return the corresponding Gaussian wavepacket values evaluated on that grid\n", " \n", " Arguments\n", " ---------\n", " x0 : float\n", " mean position of the wavepacket in atomic units \n", " sig : float\n", " spread of the wavepacket in atomic units\n", " k0 : float\n", " the mean wavenumber in atomic units of the wavepacket, related to\n", " mean momentum by \\hbar k0\n", " x : float (or numpy array of floats)\n", " the position variable for the energy eigenstate in atomic units\n", " \"\"\"\n", " ci = 0+1j # <== the imaginary unit\n", " pre = 1 / (sig * np.sqrt(2 * np.pi)) # <== prefactor\n", " gauss = np.exp(-0.5 * ((x - x0) / sig) ** 2) # <== gaussian envelope\n", " plane = np.exp(ci * k0 * x) # <== plane-wave component\n", " return pre * gauss * plane\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Step 3: Set up plot and function parameters and form the Gaussian Wavepacket at time t=t0" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "colab": {}, "colab_type": "code", "id": "QLRBwgFqdr83" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/opt/anaconda3/envs/escip/lib/python3.10/site-packages/matplotlib/cbook/__init__.py:1369: ComplexWarning: Casting complex values to real discards the imaginary part\n", " return np.asarray(x, float)\n" ] }, { "data": { "text/plain": [ "[]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAGdCAYAAAAfTAk2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABDDUlEQVR4nO3de5RU5Z3/+0/duxu6Wy7STStKYxIvIV7SKMIviLnhJcbkaM5onCHJL+qRYYwiyUqCzloQTYIxHg9xeeEX4yX55aLnLGTGNSEMOFE0A3jhEoEQRkcEArQNCt0NTdd1nz+q9q5d3bt2VTVdXbf3ay1Wunft3eyqyObD9/k+z+MxDMMQAABAFfGW+gYAAACGGwEHAABUHQIOAACoOgQcAABQdQg4AACg6hBwAABA1SHgAACAqkPAAQAAVcdf6hsohUQioQMHDqixsVEej6fUtwMAAPJgGIZ6e3vV1tYmr9e9RlOTAefAgQOaNGlSqW8DAAAMwb59+3T66ae7nlOTAaexsVFS8gNqamoq8d0AAIB89PT0aNKkSdbf425qMuCYw1JNTU0EHAAAKkw+7SU0GQMAgKpDwAEAAFWHgAMAAKoOAQcAAFQdAg4AAKg6BBwAAFB1CDgAAKDqEHAAAEDVIeAAAICqQ8ABAABVh4ADAACqDgEHAABUHQIOgLy99bejevJPuxVPGKW+FQBwVZO7iQMYmmsf+U9J0mmn1OnKqRNLfDcAkB0VHAB5Ccfi1tfv94RLeCcAkBsBB0Be3uk6Zn3dVE/xF0B5I+AAyMtfD/ZaX5+IJEp4JwCQGwEHQF7+2tljfd0XiZXwTgAgNwIOgLy8e+i49fWJSNzlTAAoPQIOgLz02ULNiSgBB0B5I+AAyEsknu676aOCA6DMEXAA5MU+TbyfCg6AMkfAAZCXSIwKDoDKQcABkBcCDoBKQsABkBd7wGGICkC5I+AAyEs4o4LDOjgAyhsBB0BeGKICUEkIOADyEo4zRAWgchBwAORkGAYVHAAVhYADICf7In8SKxkDKH8EHAA52as3EntRASh/BBwAOQ0MOLGEMegYAJQTAg6AnMIOYYZhKgDljIADICezWjM65Jff65HEMBWA8kbAAZCT2WQc9HtVH/BJooIDoLwRcADkZFZwgj6vQmbAoYIDoIz5S30DAMpfOJYMM6GAV95U2IklaDIGUL4IOAByCtsqOIaRPBaNGyW8IwBwR8ABkJM1ROX3Kp5KOLE4FRwA5YuAAyCnjICTSAYcKjgAyhlNxgByMoeoQn6v/L7kNPEoPTgAyhgBB0BO6QqOT35v8rERo4IDoIwRcADkZK2D4/MqYFZw6MEBUMYIOAByitiGqAK+5GODgAOgnBFwAORkrYPj98rvY4gKQPkbkYDz2GOPqb29XXV1dero6NCrr77qev66devU0dGhuro6TZkyRcuXL894/YknntCsWbM0ZswYjRkzRp/73Of0+uuvF/MtADXNPosqkNqLioX+AJSzogec5557TgsWLNA999yjLVu2aNasWbrqqqu0d+9ex/N3796tq6++WrNmzdKWLVt0991364477tCKFSusc15++WV99atf1UsvvaQNGzbojDPO0Jw5c7R///5ivx2gJtkDjjmLKkIFB0AZ8xiGUdSn1PTp0/XJT35Sjz/+uHXs3HPP1Ze//GUtXbp00Pnf+9739MILL2jnzp3WsXnz5unPf/6zNmzY4Ph7xONxjRkzRo888oi+9rWv5bynnp4eNTc3q7u7W01NTUN4V0BtWbpqp/7XK+/qlk+1q7OnX//21kEt/uJ5+p//o73UtwaghhTy93dRKziRSESbNm3SnDlzMo7PmTNH69evd7xmw4YNg86/4oor9OabbyoajTpe09fXp2g0qrFjxzq+Hg6H1dPTk/ELQP6sdXAC6SZjenAAlLOiBpzDhw8rHo+rpaUl43hLS4s6Ozsdr+ns7HQ8PxaL6fDhw47XfP/739dpp52mz33uc46vL126VM3NzdavSZMmDeHdANUjGk8okcg/oKSnifvk93oyjgFAORqRJmOPx5PxvWEYg47lOt/puCQ98MAD+t3vfqfnn39edXV1jj9v0aJF6u7utn7t27ev0LcAVI33e/p10b1rteC5rXlfk9Fk7KeCA6D8FTXgjB8/Xj6fb1C1pqura1CVxtTa2up4vt/v17hx4zKOP/jgg/rxj3+sNWvW6Pzzz896H6FQSE1NTRm/gFq1Ze8RHQvH9MKfD+g/33Guig5k7j8V8HmYRQWgIhQ14ASDQXV0dGjt2rUZx9euXauZM2c6XjNjxoxB569Zs0bTpk1TIBCwjv30pz/Vfffdp9WrV2vatGnDf/NAlTL7aSTpf2/Yk9c1sVTA8Xk91jo4DFEBKGdFH6JauHChfvGLX+ipp57Szp07ddddd2nv3r2aN2+epOTwkX3m07x587Rnzx4tXLhQO3fu1FNPPaUnn3xS3/nOd6xzHnjgAf3zP/+znnrqKU2ePFmdnZ3q7OzUsWPHiv12gIrXF4lbX3/YF8nrmlgqzPi9HmuaOENUAMqZv9i/wQ033KAPPvhA9957rw4ePKipU6dq1apVOvPMMyVJBw8ezFgTp729XatWrdJdd92lRx99VG1tbXr44Yd1/fXXW+c89thjikQi+spXvpLxey1evFhLliwp9lsCKtrxcMz6OhyNu5yZZlZw/D6vgtYsKio4AMpX0QOOJM2fP1/z5893fO2ZZ54ZdGz27NnavHlz1p/33nvvDdOdAbXneDgdak7kGXDi9iGq1G7i0QJmYQHASGMvKqDG9EXSFZx8A07UYYgqGqOCA6B8EXCAGnPMNkTVH80vpNgrONYQFRUcAGWMgAPUGHuTcX+ksB6cgC+9F1WUHhwAZYyAA9QYe5PxkHpwUhUcAg6AckbAAWrMcVsPTixh5BVU7NPErYX+mCYOoIwRcIAaY59FJUn9eVRx7NPEzc02mUUFoJwRcIAaY59FJeU3TGUOUWUu9McQFYDyRcABaszACk44j5lU5jCWz+tJV3AIOADKGAEHqDHHT7aC4zVnUTFEBaB8EXCAGtOXquB4kjlFJ/KYKp7Rg+M318GhggOgfBFwgBoSiSWsXcDHjQpJyq/J2F7BCZhbNcSo4AAoXwQcoIbYG4zHjQpKym+IyhyO8tm3aqCCA6CMEXCAGmJu0xD0e9VYl9xrN78KTjLMBHzpJmPWwQFQzgg4QA0xt2kYFfSpLuCTlN9+VDFrJWOvAmzVAKACEHCAGmJOCQ/50wEnnyEqs1qTnEVlThOnggOgfBFwgBoSiSfDTNDvVX0wFXDymEVl34vKrOAwiwpAOSPgADUkkpr5FPR7VR9I/vHPq4KTCjN+enAAVAgCDlBDzCniQZ/XGqIK5wg4iYQhc9spv9drzaKK0IMDoIwRcIAaEomlAo7fq/o8e3Bitk017Vs1sBcVgHJGwAFqiBVwbBWcXAEnbgs49mniCSPzNQAoJwQcoIaYU7uDfm/e08TtzcT2hf7sPw8Ayo2/1DcAYOTYh6is2VA5Qoq9mdjv9Sph+2dRjAoOgDJFBQeoIWFbk7E51JRrPRt7iPF6lFnBiVHBAVCeqOAANcRewfHnuSKx2WcT8Hnk8Xjkp4IDoAJQwQFqiBlwAj6vtSt4rpBi9uD4vMlA5PF4rK9pMgZQrgg4QA2xNxkH/PlVcNLbNKQfF2bAYTVjAOWKgAPUELOCE/J7bXtK5ZpFlQo4tt6bABUcAGWOgAPUkEjcaRaVe0gxQ4zfmw446QoOAQdAeSLgADUk3YPjsc2icq/gmK/7bAHHn7qWCg6AckXAAWpIei8qnxVSck0TT1dwHHpw2HATQJki4AA1JGOhvzwbhZ16cPz04AAocwQcoIZkroNjbpqZXwXH59iDwywqAOWJgAPUEKetGiI5p4knX7c3GVPBAVDuCDhADUn34KSbjHNVcGJuPTgEHABlioAD1BD7Qn9mT02uYaa4Yw8Os6gAlDcCDlBDwrH0LCqzghPJsWGm0zRxKjgAyh0BB6ghmbOo8tuLymmhP7OaE6fJGECZIuAANcRpN/GT6sFhHRwAZYqAA9QQs8nYvpJxJJ6QYWQPKs49OMyiAlDeCDhADTH7aUK2aeKSe1ChBwdAJSLgADUkEhu8VYPkHlSctmpgFhWAckfAAWpIRg+OrSLjtuFmjN3EAVQgAg5QQzJXMk7/8XfbcNNcydjn2IPDLCoA5YmAA9QQe5Oxz+uRWZSJUcEBUGUIOECNMAwjvVWDP/lH3+zDiRbag5PnFHMAKBUCDlAjYglD5mzwkM8nSQqaAcdlNWPnCk5+iwQCQKkQcIAaYd+SIV3Byb0flVmloQcHQCUh4AA1wj5TylwDxxx2cmsyNkNMgB4cABWEgAPUCLP/xuNJ994EU0Enn2niXq9DBSfPHhy3lZIBoBgIOECNMKs09unhVpOxawUn+2ab+VRwunr7dcmP/0NLXthR+E0DwBARcIAaYU4FDzgFFZcKTtyxgpP/Ssa/3rBHh3rDemb9ewXfMwAMFQEHqBHmMFTAn/5jb86icqvEnOw6OL3hmPX1cdvXAFBMBBygRpjDUE7r2URcKjiJVP+MzzO0WVSHj0Wsr/d+2FfAHQPA0BFwgBphVnCCvsFDTW4L9pnDUD5bMCqkgvPfXcesr/d8QMABMDJGJOA89thjam9vV11dnTo6OvTqq6+6nr9u3Tp1dHSorq5OU6ZM0fLlyzNe37Fjh66//npNnjxZHo9Hy5YtK+LdA9XBquDYmowDBfTg2C6zVXDcA04iYWj34ePW93s/PO5yNgAMn6IHnOeee04LFizQPffcoy1btmjWrFm66qqrtHfvXsfzd+/erauvvlqzZs3Sli1bdPfdd+uOO+7QihUrrHP6+vo0ZcoU3X///WptbS32WwCqQtS2D5XJnFHlNkTl1GSc70rGnT39OhGNW99TwQEwUooecB566CHdfPPNuuWWW3Tuuedq2bJlmjRpkh5//HHH85cvX64zzjhDy5Yt07nnnqtbbrlF3/zmN/Xggw9a51x88cX66U9/qhtvvFGhUKjYbwGoCjGXaeL5DFE5TRPPtQ7Okb5Ixvf7jpwo4I4BYOiKGnAikYg2bdqkOXPmZByfM2eO1q9f73jNhg0bBp1/xRVX6M0331Q0Gh3SfYTDYfX09GT8AmpNuoJjG6Ly5t6qIZ5qMvZ6Cp9F1ReJZ3zfc2Jof4YBoFBFDTiHDx9WPB5XS0tLxvGWlhZ1dnY6XtPZ2el4fiwW0+HDh4d0H0uXLlVzc7P1a9KkSUP6OUAlMwOO33GIqsAKTp6zqAZOCz/GNHEAI2REmow9tn/5Scll2wcey3W+0/F8LVq0SN3d3davffv2DennAJXMeSXjQpqMh17BGRVM7l7e208FB8DI8Bfzh48fP14+n29Qtaarq2tQlcbU2trqeL7f79e4ceOGdB+hUIheHdQ8cxjKqcm40Gni+c6iMis4LU11evfwcR3rp4IDYGQUtYITDAbV0dGhtWvXZhxfu3atZs6c6XjNjBkzBp2/Zs0aTZs2TYFAoGj3ClS7SMyhB8fcbNOtB8dhmni+s6jMCk5LU50k6Xgkntf2DgBwsoo+RLVw4UL94he/0FNPPaWdO3fqrrvu0t69ezVv3jxJyeGjr33ta9b58+bN0549e7Rw4ULt3LlTTz31lJ588kl95zvfsc6JRCLaunWrtm7dqkgkov3792vr1q165513iv12gIqV3nLBYbPNmEsFx6HJOO8KTsSs4KQrqPThABgJRR2ikqQbbrhBH3zwge69914dPHhQU6dO1apVq3TmmWdKkg4ePJixJk57e7tWrVqlu+66S48++qja2tr08MMP6/rrr7fOOXDggC666CLr+wcffFAPPvigZs+erZdffrnYbwmoSGafTdBvG6LKZxaVGYx8Q+jBCScrOKc0BBXyexWOJdTbH1VzPdVYAMVV9IAjSfPnz9f8+fMdX3vmmWcGHZs9e7Y2b96c9edNnjzZajwGkJ+I415UqQpOHj04GRUcX56zqFIVnIagT411foWPRajgABgR7EUF1IiYwzo4+Uz3jjsMbVkVnBwL/ZkVnFEhv0aHkv+e6qXRGMAIIOAANcJpq4Z8hppOZi+qzApOcliKmVQARgIBB6gRjuvg5BFUnFcyTg1t5b0Ojq2CwxAVgBFAwAFqhNNKxmZQcQ04Dk3G+a5k3Jeq4NSnenAkFvsDMDIIOECNMIehgg4rGecTcBz3osrVg2NWcEI+jU4FHIaoAIwEAg5QI8yF/gqd7u3UZFzoSsYNQb+aUj04NBkDGAkEHKBGpLdqKLAHx6zg2JuMfbmHtiTnHhymiQMYCQQcoEaYqxXbA05eFRzDZZp4vhWcULoHp4ceHAAjgIAD1Iiow2abhayDU+g0ccMwMio4DakdxU+kjgFAMRFwgBoRdVjJ2No0s8CVjH15bPEQiSesCk9DyKf6YLKC00fAATACCDhAjbBWMvYX1oOTcNykM/d19kpNfcBHBQfAiCLgADXCWsnYW9gsqphTk3Ee14VTs7a8nmTfT30q4JirGwNAMRFwgBrhuJJxHpWYhGOTcWoWlcvQljktPeRPBptRqSEqKjgARgIBB6gRzisZ5+6libk0GedTwQmmhsTMISp6cACMBAIOUCNiQ92LyqXJ2O26cCwZZMyAU28FHIaoABQfAQeoEZH44IX+rFlUQ1zJ2HUWlTVElVnBORGlggOg+Ag4QI0ww4jzppmFrWRsVnASRnqW1UCRgUNUgWQPTjRuWMNlAFAsBBygRpgrGQedVjJ2aRZ2ajK2f22udDyQWTEyfz9ziEqiDwdA8RFwgBphrmTs9xZWwXGaJu6zVYGyXRuOpoaoAslgE/R7rd+PmVQAio2AA9SIqMNCf7lmUSUShswCjVMPTvJa9wpOyFYxotEYwEgh4AA1wppFVcCKxPbhJ5/DLCop+1o4A3twJKaKAxg5BBygRqQrOPag4j6Lyh58MoaoPPYKjnP1x5wmHsoIOKnF/phJBaDICDhABTMMwwoSuThttpmrBydhq+DYr/N6PTKLONmudarg1Kf6cY6HGaICUFwEHKCCffv//bOm/fBFvXvoWM5zowNmNUm596KKZangSOnAk+3agSsZS9KoEBtuAhgZBBygQvVH43p+y3719sf0wOpdOc83e3AKWQfHvsaNf0DCyTXF3Ao4GU3GySEqenAAFBsBB6hQf9531Pp6/X8fVr9LX4thGFlWMjZDinMfTUYFx5P5Wq7VjK2VjAO2HpzUEFUfPTgAioyAA1So13d/aH3d0x/T2+9nH6ayV2gCGRUc76DX7RLWPlSSx5OZcHw5ZmClF/pLL/BnbdfANHEARUbAASrU5r1HMr4/dKw/67nRuD3g2Co4vvx6cAYOTyWPuV9rLvSX0WTMNHEAI4SAA1SofUdOSEpPw+7qCWc9N2obRrL34JjTvbOug+OwirF1bY7+nUjcaZo4TcYARgYBB6hAhmHowNFkwLlg0imSpK5el4ATSwcc+0J/9llUhsOeUk77UJlyzaJynCZOkzGAEULAASpQz4mYFRIuOL1ZktTVm32IygwhPq9HXoe9qKTkzuDZrhvYYCzZV0HO0WTMSsYASoCAA1Sg/anqzdhRQZ0xtkGS+xCVGTbsDcZS5qaZTrOhzCZjv2/woyLfaeKOQ1RRmowBFBcBB6hA5vBU2yl1OrWxTpJ06Fj2gGNWYgIDhprsFRynXpp0BWdwCSfXGjruKxlTwQFQXAQcoAId7E4FnOZ6TWgKScrRZOywk7iUuWmmUy9N3BraGvwzc+1jZU0Tz1jJOLUXFUNUAIqMgANUoP1Hk/02bafU69TRyYBzqDfs2CgspQOOf0Azjb15OOEQVNybjN0rOOY08ZA/vQ6ONU2cISoARUbAASpQZ6qCM7G5Tqc2JgNOJJ5Qzwnn4GD2yQQGlGLsecepEhPLY5p41nVwHPa+slYypoIDoMgIOEAFMvttJjSFVBfwWY28veGo4/nWENWAJmOPx+NaiUnksdBfrllUwYwmY4aoAIwMAg5QgQ6l1rw5dXSywbixLhkcevudKzjRLBUcyb0S4zZNPGcFJzZ4oT9WMgYwUgg4QAWyAk5qeGp0qnn3WDhbwEn14DgEHKsS4zDdO2FbP2fQdbn2onKs4LCSMYCRQcABKkw0ntCRvuRQ1PjRQUlSY11AknQsSwXHXOMm6BscVHwuu4KnFwh0qvykZlFlWQfHLeBE4omsO5gDwHAg4AAV5oNjEUnJYDKmIRlwzApOT79zD04kln3BPvOYUyUmbmSfJp5zFlUs+ywqSeqLUsUBUDwEHKDCmMNT40cHrW0XRte5D1GZ1ZmBTcaSey9NwrWC496D47RVQ9Dnta5jmApAMRFwgApz6FhyDRyz/0ZKNxlnG6JKz6IqbD0ba4jKaS+qHLOonH5Pj8fDVHEAI4KAA1SYw73JISpzgT9JagwVZxaVW5Ox23WGYaS3hxiQjsxhquNZqk0AMBwIOECFMdfAGW8LOLmGqLKtZGw/5lSJibnNonKp/ERtjccDt4ewtmugBwdAERFwgAozcIq4JI0OJWdRZavgWCsZ+10qOE7TxA23Ck72vaiithlSwQFVo3qGqACMAAIOUGGcAo7Vg5NrJWPHSozLLCqXJmP3Ck5i0Hmm9Fo47kNUiYShwy47pAOAGwIOUGHMISqngFOslYydmox9qYNRh/VszJ3EPZ7B1Z98VzO+e+U2Tfvhi5r/m03qZzgLQIEIOECFOWxt02AfojqJlYxdViR2mybuOvvKFqg8HucKjlvA2XGgW8++sU+StGpbp3772t6s5wKAEwIOUGGsdXAyKjg5VjKO57OSsUsFp8DdxN2GxPLZcPN/b9iT8f0z69/LuqAgADgh4AAVpD8aV2+qSpPZZGyuZOwccCJxl5WMXWZRuTUZ59OD49TUnM8Q1Za9RyVJP7vxQjXV+bX3wz699u4HWc8HgIEIOEAFMas3Ib/XWvtGyt1kHHNZ6M+tEuPaZOzLvheVW8+PtdBf1DmM9UVierurV5I0Y8o4XTm1VZK0eken4/kA4ISAA1QQe4OxvbfF7Gvpjyasvhm79KrCQ5xFVeBKxlFrSMwh4OTYUXz7/h4lDKm1qU4Tmup01dSJkqTV2zsd3xsAOCHgABXEaYq4lLmJpdMCetFUMPC77SnlUIlxq+Dk04Pjd0hG9akenGxDVG/97agk6fzTmyVJMz8yTo0hv7p6w9qy74jjNQAwEAEHKAPHwzG99bej6suxNkx6o83MgFPnzxFwYmZPTGG9NG5Nxm7XmbuXOw5RWT04zu/13cPHJUnntDZKSu5G/plzJ0hKVnEAIB8jEnAee+wxtbe3q66uTh0dHXr11Vddz1+3bp06OjpUV1enKVOmaPny5YPOWbFihc477zyFQiGdd955WrlyZbFuHygawzD06417dPGPXtS1j/ynPvWTl/Sntw9nPf/9nuRGmy1NmQHH6/WoLpD84+w09GPtC1VgJcZ9L6rsKxmndy93CzjOFZx9H/ZJkiaNbbCOXfnxZB/OH7Z3yjAYpgKQW9EDznPPPacFCxbonnvu0ZYtWzRr1ixdddVV2rvXeV2L3bt36+qrr9asWbO0ZcsW3X333brjjju0YsUK65wNGzbohhtu0Ny5c/XnP/9Zc+fO1d/93d/ptddeK/bbAYZNImHo3n/7i/75X7Zbf9l/eDyiO5/dknUF3wNHkwFnYnP9oNes6dcOFZyIWw+OL3svzdD3osr++zXkGKLamwo4Z9gCzuyzT1VdwKu/HTmhHQd6HK8DADt/7lNOzkMPPaSbb75Zt9xyiyRp2bJl+vd//3c9/vjjWrp06aDzly9frjPOOEPLli2TJJ177rl688039eCDD+r666+3fsbnP/95LVq0SJK0aNEirVu3TsuWLdPvfve7Yr+lrBIJw/qLBJCSTbZeh3BwLBzT91a8pd+/dVCS9L0rz9HXZ56p6x5br7929urRl97R4i9+fNB1B7tPSJLaTqkb9JrbHk8xl4X+3Cox1jRxT2Hr5+QzROVYaYontP9I8j2eMa7Bdo1fl39sglbv6NTq7Z2aelrzoGuj8YRe+muXNu09onA0oYagT63NdTpz3CidObZBp42pd7wfk2EYMozke04Y6fcOYOjqAr7cJxVJUQNOJBLRpk2b9P3vfz/j+Jw5c7R+/XrHazZs2KA5c+ZkHLviiiv05JNPKhqNKhAIaMOGDbrrrrsGnWOGooHC4bDC4fS/iHt6ivMvwPc+OK7P/N/rivKzUZnqAz6dNWGUzjp1tM4c26AJTXV6v6df/9+bf1NnT7/8Xo8e/D8v0JcvOk2S9P2rztE3nn5DKzb9Td+94pyM5mFJOtidvYJT7xIczGnbTrOa3Cox7tPE3So/2Ss49S49OAe7+xVLGAr6vGppzAxxV05t1eodnfq3tw7ors9/LKOq9Orbh3TPyu1W9ScbrycZurwejxK2QBNPfQ1g+Ew5dZT++O3LS/b7FzXgHD58WPF4XC0tLRnHW1pa1Nnp3CzY2dnpeH4sFtPhw4c1ceLErOdk+5lLly7VD37wg5N4J8DQnIjGtX1/j7bvHxyqTzulXstuvFAXTx5rHbvso6dq0th67fvwhP6w/aCu++Tp1muGYejA0WR1Y2Jz9grOCYf1ZdxmNXk9+ayDM/i9uc2+irqsu+NWwdl3JBlQTh9TP6jy9bnzWtRU59d7H/Tp99sO6toL2pRIGHr4j2/rZ//xtgxDGj86qCuntuqU+qCOhWPaf/SE9nxwXHs/7EtOoTekcIwqK1ALij5EJWnQXjSGYQw6luv8gccL+ZmLFi3SwoULre97eno0adKk/G6+AJPHjdKOH1wx7D8XlclQsin4v7uO6b8PHde+I3061BtWc31Al04Zpy9eMFEhf2aFxuv16P+48DQ9/Md39OLO9zMCzpG+qPWXc6tbwIlkX5fGKXAMuYLj1oOTzywqh14hs8H4dFv/jWl0yK+bPzVF/8+L/6Uf/f4vCng9+t0b+/TKfx2SJN00/Qzdc/W5GhUa/FgzDEPdJ6KKxBOKxg0lEoa8Xo+8nmTA83iSw3De1C+PN3V80E+qPRS2MFQOo/MjqqgBZ/z48fL5fIMqK11dXYMqMKbW1lbH8/1+v8aNG+d6TrafGQqFFAqFHF8bTl6vx/Hhito1+tTROuvU0QVd8+lzJujhP76jV//rsKLxhBUSzOrN+NHBQcFIsg1ROQSH9OaXDr00vuyVGPe9qLL37rg1Nbutg9PZnRxKPs2hx0iSbp7Vrn9764De7jqmf/zNZklSXcCrH335E7q+43THa6TkP4hOaQhmfR1A9SnqLKpgMKiOjg6tXbs24/jatWs1c+ZMx2tmzJgx6Pw1a9Zo2rRpCgQCrudk+5lAJbng9FM0blRQveGY3njvQ+u4W/+NZK/gZB+icq/guOxF5VAddd9N3GWIKnWfkVhi0LXv9ybf46mNzgFndMivX918ieac16Lxo0P6zDkTtHL+/3ANNwBqU9HLDQsXLtTcuXM1bdo0zZgxQz//+c+1d+9ezZs3T1Jy+Gj//v361a9+JUmaN2+eHnnkES1cuFC33nqrNmzYoCeffDJjdtSdd96pyy67TD/5yU/0pS99Sf/6r/+qF198UX/605+K/XaAovN6PZp99ql6fvN+vfTXLs08a7wk6d1DxyRlzi6ya3Cp4ERdNtsc6l5U6euchsSyD1HZG6f7IjFrJ3RJ6sqyzo/dxOZ6/fxr07K+DgDSCKyDc8MNN2jZsmW69957deGFF+qVV17RqlWrdOaZZ0qSDh48mLEmTnt7u1atWqWXX35ZF154oe677z49/PDD1hRxSZo5c6aeffZZPf300zr//PP1zDPP6LnnntP06dOL/XaAEfHZc5LDrf/x1y7r2NtdyYDzsQmNjtfUuSyg574XVT49OIN/P9eVjF1+v5Dfa43ND7zXrtRKzQNnUAFAoUakYWT+/PmaP3++42vPPPPMoGOzZ8/W5s2bXX/mV77yFX3lK18ZjtsDys6sj42X3+vRu4eOa88Hx3XmuFF6+/3kDtsfbXHu6WkIuPTgJLJXVHz5bLZZ4ArIMZcKjsfjUUPQr2Ph2KCAk16pmYAD4OSwFxVQhprqApo2eYwk6Y9/7ZJhGOkKTpaA47YOTiSWuwen0Gni6XVwCpsmLjnvRxVPGNZeWxNchqgAIB8EHKBMfeac5AaTf/xrl/YfPaG+SFwBn0dnjhvleL5bwDH7ZPyOe0q5DFGlmoy9jisZp2ZRua6D4zxP1GktnA+OhZUwklNLx41ixhOAk0PAAcqUGXBee/dD/cfOZC/ORyY0Zq2KWFs1OO1FlarghPyFVXDMY07ByH0vquxDVJLzVPEu207pTs3QAFAIniJAmTrr1NH6WMtoReIJLX5hhyTpio87r/Ukpasi/S5DVEGHgONz2XLBfTfx5LGo4yyqfIeo0vdq9t8wPAVgOBBwgDLl8Xh022VnZRy79oK2rOfXuWy26VZRya8Hp8CVjHMMUZkLYh4Pp3tw3u9hBhWA4UPAAcrYtRe26dIpY1UX8Oq6T56mKS6rIjekhn0GzqIyjPQu944VnLxmUQ3+/dz2oorkqOA01SXvtftE1DrW1WtWcAg4AE4e+woAZSzg8+rZ/2tGXuemVzLODDhRWwApuIJjuFVwsgcjt2niktRcn1zczx5wzArOhEaGqACcPCo4QJXItheVWU2RnJuMrVlUDpWYvCo4Qxiicgo4XayBA2AYEXCAKlGfpQcnGksHnKH24DhNEw+4NCfnajI2A06PvYLTm3ubBgDIFwEHqBLWLKosFRyf1+M6G8opqMStaeKFrWSca5q4cwUn1WRMBQfAMCDgAFWi3rY6sGGkQ0d6FWPn4SJzReKCVzJ26cGxKjgOQ2LS4IATiyd0+Bg9OACGDwEHqBJmwEkYmX031gyqLNUU11lULk3GPpdgZAUch4qRNDjgfHA8kl7FeDQBB8DJI+AAVcLswZEyZ1JFXaaISyexF5XrbuLuQ1RNAwKOucjf+NEhx2E0ACgUAQeoEgGf1xqGss+kslYxzlrBcdmLyqXJ2H6dfUhMSg45SfkPUR3sTgacic303wAYHgQcoIo4rWacqx8mnwqOU5OxfX+qgeEo1xCVWcEJxxLqj8Z18OgJSdLE5nrH8wGgUAQcoIo47dIdzruCk30WlUO+yRhKGhiOrFlUWUJVY8gvsyjUcyKaruCcQgUHwPAg4ABVxFrNOGqv4Lj3w5jVGactF8wmY+cKTvpY1gpOlt/T6/WoqS61Fk5/VAdSAaeNCg6AYULAAapIncN2DW47iUv59eC4rWQsOVVw3KemS+k+nKN9UXV2p4aoqOAAGCYEHKCKNDhs1xDNMU3c7xtak7F7D4571UhKr3dzsLtfB46aTcZUcAAMDwIOUEXqHXpw8q3gFNpk7PV6rD6a2ID+nWjMfYhKkiaNbZAk7f2wz5om3kYFB8AwIeAAVaQ+4Jc0YJp4juEit/Vs3JqM3a6NJnIPUU0ak6zWbNpzRLGEIZ/XowmNBBwAw4OAA1SR9HYNQ6ngDJ5FlXBpMs64Nl74ENXpqQrOH//aJUlqHz+KRf4ADBsCDlBFGgKDN9zMNaPJbU+pmEuTcbZrEwnD+t51iGpMQ8b3H29rynouABSKgANUEfuGm6bh6MFx2osq27VRWyXIdYhqbGZD8dS25qznAkChCDhAFUk3GadDRq5ZVNY0cad1cMyA4zCLSnLuwYnafo5bBWdic33GTCwqOACGEwEHqCLphf7yr+Dks1VDtiZjp/4dcwaV5B5wfF6PbrxkUuo8jz5OBQfAMPKX+gYADB+nrRpy7eztttBfriZjv0OTsTlE5fUoZ9PwfV+aqs+e0yK/z6PmhoDruQBQCAIOUEWcNtvMv4IzeBZVLFcFx+fQg5PHDCqTx+PRp8+ZkPM8ACgUQ1RAFXFbyThXBSdhSIaRORvK/DZ7BWfwLKp8FvkDgGLjCQRUkXqXvahCWSs4zptmxm1hJ1uTsWMPTh77UAFAsRFwgCpS71rByRJSbMftQ032sFPISsaFDFEBQLHwBAKqiFMFJ5xrs80sm2bav846ROXYg8MQFYDS4wkEVJGG4OC9qKyemBwL/UkDKjhG7gqOuQCgfQ0dhqgAlAMCDlBF6oPJP9IZs6hyLfTnca7gJPKp4DitZMwQFYAywBMIqCL1ThWcuPs0ca/XI7OIY28WtoeWbMvZOK2hwxAVgHLAEwioImYPTiSWsEKHtQ6OS+DItmmmlAwxnhxbNTCLCkC5IeAAVcRcB0dKV3FyrWQs2aZ723ppYjn2obJfRwUHQLnhCQRUEftaN+aO4uFU0DFXOXbiNN071z5U9uvowQFQbngCAVXE4/FYw1T9qR3FzUqO2YDsxGnLhVz7UEm2WVQOFRw/Q1QASoiAA1QZc5iqL7WjuLkmTqEVHGsfKpec4lzByd3zAwDFxhMIqDJ1Axb76zcrOC4Bx2nLBbPJ2O/Wu5Oq0sTj9iZjhqgAlB5PIKDKDNxwsz+aDB/uFZzBQ03pCk72Eo5bBSfbwoIAMBJ4AgFVxtqPKhJXLJ6wFvrLr4IzuMnYrRDjOovKbWwLAIqMgANUGWs/qmhc/bH00FF9cGizqNyajJlFBaBc8QQCqowZZPoicav/RsqcQj6Q0zo45l5UbtPE3WZRBfxUcACUDgEHqDJmD05/NG6bQeXNuhqx5DzUlBhyBSeR8zoAKDaeQECVMZuJ7RUct/4bKb1mjdNeVG6tNOlgNHgWVba9rwBgJPAEAqpMg63J2JxBlSvgOA01nWwFh72oAJQSAQeoMvYm4xN5bNMgOQcVq4LjUsKxVkCOM0QFoLzwBAKqTH3QLylZwck34Dj14JhNxm6ToZxmX0VjDFEBKD2eQECVqbf14JhNxm5TxCXnCk7CWgcn915U9t6daIIhKgClR8ABqkx6JeOYwrH8moydmoXNsOOWUxwrOKyDA6AM8AQCqsyoUHKI6lg4c5q4G7/DOjjpCk7u6eUZPTgxczdxHi8ASocnEFBlmuqSAae3P1pAD072vajcmoXNYSinhf6CDFEBKKGiBpwjR45o7ty5am5uVnNzs+bOnaujR4+6XmMYhpYsWaK2tjbV19fr8ssv144dOzLO+fnPf67LL79cTU1N8ng8OX8mUEsa6wKSpJ4T0QKmiSf/13kvKrcKjtmDYws4CYaoAJReUZ9AN910k7Zu3arVq1dr9erV2rp1q+bOnet6zQMPPKCHHnpIjzzyiN544w21trbq85//vHp7e61z+vr6dOWVV+ruu+8u5u0DFampPlnB6emPFTBNPHsFxy3gOM+iYogKQOn5i/WDd+7cqdWrV2vjxo2aPn26JOmJJ57QjBkztGvXLp199tmDrjEMQ8uWLdM999yj6667TpL0y1/+Ui0tLfrtb3+r2267TZK0YMECSdLLL79crNsHKlZTRgUnv1lUzruJm+vZ5NGDk7GSMUNUAEqvaP/E2rBhg5qbm61wI0mXXnqpmpubtX79esdrdu/erc7OTs2ZM8c6FgqFNHv27KzXAMjUVJ8MOOFYQt19UUn5L/Rnn0WVyimFV3CslYyp4AAonaJVcDo7OzVhwoRBxydMmKDOzs6s10hSS0tLxvGWlhbt2bNnyPcSDocVDoet73t6eob8s4By1xjyy+ORDEM6dCz5332+08QdKzgulRin6yLsRQWgDBT8BFqyZIk8Ho/rrzfffFOSHHcvNgzDdVdjp+vyucbN0qVLrUbn5uZmTZo0acg/Cyh3Xq9Ho1OrGb/f0y8pj2ni5myouFMPjsteVA6zqCKptXeo4AAopYIrOLfffrtuvPFG13MmT56st956S++///6g1w4dOjSoQmNqbW2VlKzkTJw40Tre1dWV9Zp8LFq0SAsXLrS+7+npIeSgqjXVB9QbjqmzOxlwGvLswTG3Z5DSocW9Byc1iyrOQn8AykvBAWf8+PEaP358zvNmzJih7u5uvf7667rkkkskSa+99pq6u7s1c+ZMx2va29vV2tqqtWvX6qKLLpIkRSIRrVu3Tj/5yU8KvVVLKBRSKBQa8vVApWlMrYXzwfGIJGncKPf//odzFlUkNYsqxBAVgBIq2hPo3HPP1ZVXXqlbb71VGzdu1MaNG3XrrbfqmmuuyZhBdc4552jlypWSkkNTCxYs0I9//GOtXLlS27dv1ze+8Q01NDTopptusq7p7OzU1q1b9c4770iStm3bpq1bt+rDDz8s1tsBKorZaGw6tdE94Dj34ORTwck+i4oKDoBSKlqTsST95je/0R133GHNirr22mv1yCOPZJyza9cudXd3W99/97vf1YkTJzR//nwdOXJE06dP15o1a9TY2Gids3z5cv3gBz+wvr/sssskSU8//bS+8Y1vFPEdAZXBnCpuGp8j4DhVYsxhp3wqODGHCg5NxgBKqagBZ+zYsfr1r3/teo5hG/OXklWcJUuWaMmSJVmvyfU6UOvM7RpM40cHXc932lMqn3VwzCpNNG6fRcVu4gBKj39iAVXIPkTVVOdXyF/4Ojj5zKJKB5zkdYZhWAGHCg6AUuIJBFShZlvAydV/IznvKWX14LhUYoL+5GtmwIknDJlF2SA9OABKiCcQUIU+3tZkfT1+dO6A47SeTT6zqKwKTqrvxqzeSFRwAJQWTyCgCl3SPtb62pvHIplDnUVlBhxz9eJozBj0GgCUAk8goAqd0pBuKt59+HjO8x1nUaX6cfKq4MQzKzgej3swAoBiI+AAVepLF7ZJkm6Z1Z7z3KFWcIJZAk7A5z2p7VUA4GQVdZo4gNK5/7rzdcPFk3Tx5LE5z3WcRRXPYxZVqsnYXPvG7MUJMTwFoMQIOECVqg/6NPOs3NuqSM57ShXSgxNLGEok0lPEAzQYAygxnkIAsvTgJL/2ug1R2YJMNJGwKjks8geg1Ag4AE66B0dKrmbMIn8AygVPIQBZ1sHJfxaVlOy/icbYaBNAeeApBMBxV3Bzzb5cu4mbL0fjiXQFh4ADoMR4CgFw7MGJ51HBkeyL/SWs6eIMUQEoNZ5CABz3oorlsReVZF8Lx7CajKngACg1nkIAslRwcq+DI6WnhCeHqJLX0IMDoNR4CgFI9+DEHSo4OYeo0ov9WRUchqgAlBhPIQA5Kjj59eBEbT04VHAAlBpPIQCOs6jyreDYe3DMgBOiggOgxHgKAXBcB6fQWVTROCsZAygfBBwAzrOo4mYFJ1eTcaoHx74ODhUcACXGUwiAfJ6h9+BYQ1QxewWHRwuA0uIpBMB9L6ocw00Bhx4cAg6AUuMpBCDLXlR5VnD85krGcauCQ5MxgFLjKQTAtg6OfS+qfNfBMYeoDEVZ6A9AmeApBMBxHZx8dhOXbAv9xRMKs9AfgDLBUwiAew9OrllULPQHoAzxFAJghZiE4dSD435t0GEdHCo4AEqNpxAA5wpOPM/NNh1mUQVZ6A9AiRFwAFg9OIYhJVIhJ+/NNv3pzTb7o3FJUijgK9atAkBeCDgA5LNVXMxgM5TNNk+kAk5DkIADoLQIOAAyqjRmsIkbhW62mdCJSDLg1FPBAVBiBBwAGVWaWCIhwzCGUMExrAoOAQdAqRFwAGRMBY8njIz1cPKdJh6xDVHVMUQFoMQIOABkL9LEEkbGbCpfjhlR5pTwaCyhE5HkLCoqOABKjYADQB6PJ2M148wKTn4rGUfj6VlUBBwApUbAASApcy2cjApO3pttJtQXiUliFhWA0iPgAJBk248qnlnB8XnyazI+Fo7LvIweHAClRsABIMlewUlYG216PZI3RwXHrNZ8cCxsHWOICkCpEXAASJL8qUqMvQcn1wwqSRoV9EuSDqcCjt/rYbNNACXHUwiApAE9OPH81sCRpFEhM+BEJFG9AVAeCDgAJMlxFlWuGVSSNDoVcMxr6L8BUA4IOAAkOc+iyrUGjiSNCmUGGmZQASgHBBwAkuwVnMSQKjgmhqgAlAMCDgBJ6QpOJGZYs6gK6cEx1RFwAJQBAg4ASen1bGIZFZzcj4iGoE/2pXKo4AAoBwQcAJLSKxLH4ukenDzyjTwejzVVXJLq6cEBUAYIOAAkZe4KXkgFR8psNCbgACgHBBwAkjI3zYzGEhnHcrH34TBEBaAcEHAASEpXcKLxhCLxRMaxXEYTcACUGQIOAElS0Aw4MUPR1ErGQwo4DFEBKAMEHACSMntwoqkKTjDPgGMfohq4Lg4AlAIBB4AkyW/vwTGHqPz59eDYQ83U05qG/+YAoEAEHACSbENU8YQiscJ6cMKxuPX1J88YM/w3BwAFIuAAkGRvMi68B+evnb3W16c0BIf/5gCgQAQcAJLSw1GRWOE9OF+64DRJ0owp44pzcwBQoKIGnCNHjmju3Llqbm5Wc3Oz5s6dq6NHj7peYxiGlixZora2NtXX1+vyyy/Xjh07rNc//PBDfetb39LZZ5+thoYGnXHGGbrjjjvU3d1dzLcCVD37Vg1WD06e6+DcNnuKHv/7T+p/fa2jaPcHAIUoasC56aabtHXrVq1evVqrV6/W1q1bNXfuXNdrHnjgAT300EN65JFH9MYbb6i1tVWf//zn1dubLIEfOHBABw4c0IMPPqht27bpmWee0erVq3XzzTcX860AVS9oG6IqdB2cuoBPV31ioprqAkW7PwAoRNHmc+7cuVOrV6/Wxo0bNX36dEnSE088oRkzZmjXrl06++yzB11jGIaWLVume+65R9ddd50k6Ze//KVaWlr029/+VrfddpumTp2qFStWWNecddZZ+tGPfqR/+Id/UCwWk9/PFFVgKKxp4rGEorFUD46fUWwAlaloT68NGzaoubnZCjeSdOmll6q5uVnr1693vGb37t3q7OzUnDlzrGOhUEizZ8/Oeo0kdXd3q6mpKWu4CYfD6unpyfgFIJN9JeNCe3AAoNwU7enV2dmpCRMmDDo+YcIEdXZ2Zr1GklpaWjKOt7S0ZL3mgw8+0H333afbbrst670sXbrU6gNqbm7WpEmT8n0bQM0wm4wz1sHJswcHAMpNwQFnyZIl8ng8rr/efPNNSZLHM/jhaBiG43G7ga9nu6anp0df+MIXdN5552nx4sVZf96iRYvU3d1t/dq3b18+bxWoKQHv0HtwAKDcFNywcvvtt+vGG290PWfy5Ml666239P777w967dChQ4MqNKbW1lZJyUrOxIkTreNdXV2Drunt7dWVV16p0aNHa+XKlQoEsjc3hkIhhUIh13sGap1ZrYlkVHAIOAAqU8EBZ/z48Ro/fnzO82bMmKHu7m69/vrruuSSSyRJr732mrq7uzVz5kzHa9rb29Xa2qq1a9fqoosukiRFIhGtW7dOP/nJT6zzenp6dMUVVygUCumFF15QXV1doW8DwABmQ3HU1mQcpMkYQIUq2tPr3HPP1ZVXXqlbb71VGzdu1MaNG3XrrbfqmmuuyZhBdc4552jlypWSkkNTCxYs0I9//GOtXLlS27dv1ze+8Q01NDTopptukpSs3MyZM0fHjx/Xk08+qZ6eHnV2dqqzs1PxeNzxXgDk5tRkTA8OgEpV1DnVv/nNb3THHXdYs6KuvfZaPfLIIxnn7Nq1K2ORvu9+97s6ceKE5s+fryNHjmj69Olas2aNGhsbJUmbNm3Sa6+9Jkn6yEc+kvGzdu/ercmTJxfxHQHV62TWwQGAclPUgDN27Fj9+te/dj3HMIyM7z0ej5YsWaIlS5Y4nn/55ZcPugbAyXOu4BBwAFQmnl4AJKWHo5IBJ9WDQ8ABUKF4egGQZGsyjhvpCo6fHhwAlYmAA0CSvQcnoUiMISoAlY2nFwBJtr2o6MEBUAV4egGQJPnpwQFQRXh6AZBkG6KKGVRwAFQ8nl4AJGVOE4+w0B+ACkfAASApy15UbNUAoELx9AIgKbOCE6MHB0CF4+kFQFJ6Y81YnB4cAJWPpxcASekwE0sYCkfpwQFQ2Qg4ACRlhpm+aDx1jEcEgMrE0wuApMwwE0+kenBoMgZQoXh6AZDkXK2hggOgUvH0AiBJ8nk98g5ouaEHB0ClIuAAsAys2FDBAVCpeHoBsIT8BBwA1YGnFwBLY13A+trn9cg3cMwKACoEAQeApbHOb31N/w2ASkbAAWBpslVw6gO+Et4JAJwcAg4Ai72CM6YhWMI7AYCTQ8ABYLEHnFMaAi5nAkB5I+AAsDTVp0PNKVRwAFQwAg4ACxUcANWCgAPAYp8mTg8OgEpGwAFgsc+iOqWeCg6AykXAAWDJGKIaRQUHQOUi4ACwZE4Tp4IDoHIRcABYMmZR1VPBAVC5CDgALE3MogJQJQg4ACz2WVQEHACVjIADwJIxi4pp4gAqmD/3KQBqRX3Qp6f/58WSpNEhHg8AKhdPMAAZPn32hFLfAgCcNIaoAABA1SHgAACAqkPAAQAAVYeAAwAAqg4BBwAAVB0CDgAAqDoEHAAAUHUIOAAAoOoQcAAAQNUh4AAAgKpDwAEAAFWHgAMAAKoOAQcAAFSdmtxN3DAMSVJPT0+J7wQAAOTL/Hvb/HvcTU0GnN7eXknSpEmTSnwnAACgUL29vWpubnY9x2PkE4OqTCKR0IEDB9TY2CiPxzOsP7unp0eTJk3Svn371NTUNKw/G2l8ziODz3lk8DmPHD7rkVGsz9kwDPX29qqtrU1er3uXTU1WcLxer04//fSi/h5NTU384RkBfM4jg895ZPA5jxw+65FRjM85V+XGRJMxAACoOgQcAABQdQg4wywUCmnx4sUKhUKlvpWqxuc8MvicRwaf88jhsx4Z5fA512STMQAAqG5UcAAAQNUh4AAAgKpDwAEAAFWHgAMAAKoOAWcYPfbYY2pvb1ddXZ06Ojr06quvlvqWKsorr7yiL37xi2pra5PH49G//Mu/ZLxuGIaWLFmitrY21dfX6/LLL9eOHTsyzgmHw/rWt76l8ePHa9SoUbr22mv1t7/9bQTfRflbunSpLr74YjU2NmrChAn68pe/rF27dmWcw2d98h5//HGdf/751kJnM2bM0B/+8AfrdT7j4li6dKk8Ho8WLFhgHeOzHh5LliyRx+PJ+NXa2mq9Xnafs4Fh8eyzzxqBQMB44oknjL/85S/GnXfeaYwaNcrYs2dPqW+tYqxatcq45557jBUrVhiSjJUrV2a8fv/99xuNjY3GihUrjG3bthk33HCDMXHiRKOnp8c6Z968ecZpp51mrF271ti8ebPx6U9/2rjggguMWCw2wu+mfF1xxRXG008/bWzfvt3YunWr8YUvfME444wzjGPHjlnn8FmfvBdeeMH4/e9/b+zatcvYtWuXcffddxuBQMDYvn27YRh8xsXw+uuvG5MnTzbOP/98484777SO81kPj8WLFxsf//jHjYMHD1q/urq6rNfL7XMm4AyTSy65xJg3b17GsXPOOcf4/ve/X6I7qmwDA04ikTBaW1uN+++/3zrW399vNDc3G8uXLzcMwzCOHj1qBAIB49lnn7XO2b9/v+H1eo3Vq1eP2L1Xmq6uLkOSsW7dOsMw+KyLacyYMcYvfvELPuMi6O3tNT760Y8aa9euNWbPnm0FHD7r4bN48WLjggsucHytHD9nhqiGQSQS0aZNmzRnzpyM43PmzNH69etLdFfVZffu3ers7Mz4jEOhkGbPnm19xps2bVI0Gs04p62tTVOnTuX/Bxfd3d2SpLFjx0risy6GeDyuZ599VsePH9eMGTP4jIvgn/7pn/SFL3xBn/vc5zKO81kPr7ffflttbW1qb2/XjTfeqHfffVdSeX7ONbnZ5nA7fPiw4vG4WlpaMo63tLSos7OzRHdVXczP0ekz3rNnj3VOMBjUmDFjBp3D/w/ODMPQwoUL9alPfUpTp06VxGc9nLZt26YZM2aov79fo0eP1sqVK3XeeedZD3M+4+Hx7LPPavPmzXrjjTcGvcZ/z8Nn+vTp+tWvfqWPfexjev/99/XDH/5QM2fO1I4dO8rycybgDCOPx5PxvWEYg47h5AzlM+b/h+xuv/12vfXWW/rTn/406DU+65N39tlna+vWrTp69KhWrFihr3/961q3bp31Op/xydu3b5/uvPNOrVmzRnV1dVnP47M+eVdddZX19Sc+8QnNmDFDZ511ln75y1/q0ksvlVRenzNDVMNg/Pjx8vl8gxJoV1fXoDSLoTE79d0+49bWVkUiER05ciTrOUj71re+pRdeeEEvvfSSTj/9dOs4n/XwCQaD+shHPqJp06Zp6dKluuCCC/Szn/2Mz3gYbdq0SV1dXero6JDf75ff79e6dev08MMPy+/3W58Vn/XwGzVqlD7xiU/o7bffLsv/pgk4wyAYDKqjo0Nr167NOL527VrNnDmzRHdVXdrb29Xa2prxGUciEa1bt876jDs6OhQIBDLOOXjwoLZv387/DzaGYej222/X888/rz/+8Y9qb2/PeJ3PungMw1A4HOYzHkaf/exntW3bNm3dutX6NW3aNP393/+9tm7dqilTpvBZF0k4HNbOnTs1ceLE8vxvetjblmuUOU38ySefNP7yl78YCxYsMEaNGmW89957pb61itHb22ts2bLF2LJliyHJeOihh4wtW7ZYU+3vv/9+o7m52Xj++eeNbdu2GV/96lcdpyCefvrpxosvvmhs3rzZ+MxnPsNUzwH+8R//0WhubjZefvnljOmefX191jl81idv0aJFxiuvvGLs3r3beOutt4y7777b8Hq9xpo1awzD4DMuJvssKsPgsx4u3/72t42XX37ZePfdd42NGzca11xzjdHY2Gj9PVdunzMBZxg9+uijxplnnmkEg0Hjk5/8pDXtFvl56aWXDEmDfn396183DCM5DXHx4sVGa2urEQqFjMsuu8zYtm1bxs84ceKEcfvttxtjx4416uvrjWuuucbYu3dvCd5N+XL6jCUZTz/9tHUOn/XJ++Y3v2k9D0499VTjs5/9rBVuDIPPuJgGBhw+6+FhrmsTCASMtrY247rrrjN27NhhvV5un7PHMAxj+OtCAAAApUMPDgAAqDoEHAAAUHUIOAAAoOoQcAAAQNUh4AAAgKpDwAEAAFWHgAMAAKoOAQcAAFQdAg4AAKg6BBwAAFB1CDgAAKDqEHAAAEDV+f8B5GH4/qLaMeMAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "### Compute the Gaussian wavepacket\n", "psi_gp = gaussian_wavepacket(x0, sig, k0, x)\n", "plt.plot(x, psi_gp)" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Moske6KID6eq" }, "source": [ "##### Step 3: Determine the expansion coefficients for the Gaussian Wavepacket in the PIB basis" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "colab": {}, "colab_type": "code", "id": "8-mSLc-eD6er" }, "outputs": [], "source": [ "### Create an array of quantum numbers for the PIB states... 1 to 100 should be adequate\n", "n_array = np.linspace(1,100,100, dtype=int)\n", "### Each quantum number n has a corresponding (complex) coefficient c_n \n", "cn_array = np.zeros(len(n_array),dtype=complex)\n", "\n", "for i in range(0,100):\n", " ### multiply psi_n by gaussian wavepacket\n", " integrand = np.conj(energy_eigenfunction(n_array[i], L, x) ) * psi_gp\n", " ### get coefficient c_n from the integral of psi_n * Psi_gp\n", " cn_array[i] = np.trapz(integrand, x)\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Z3SGC3GYD6ev" }, "source": [ "#### Step 4: Put it all together and animate!" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 391 }, "colab_type": "code", "id": "mXYEgVEOD6ew", "outputId": "7e54712c-8450-4be9-b158-82e2d31bf939" }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", " \n", "
\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
\n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N_time = 300\n", "\n", "\n", "y = np.zeros(len(x),dtype=complex)\n", "t = np.zeros(N_time)\n", "\n", "\n", "# animation function. This is called sequentially \n", "def animate(i):\n", " y = np.zeros(len(x),dtype=complex)\n", " for j in range(0,100):\n", " ft = energy_eigenfunction_phase(n_array[j], L, i * 10)\n", " fx = energy_eigenfunction(n_array[j], L, x)\n", " y = y + cn_array[j] * fx * ft\n", " t[i] = i*10\n", " line.set_data(x, np.real(y))\n", " return (line,)\n", " \n", "\n", "anim = animation.FuncAnimation(fig, animate, init_func=init,\n", " frames=N_time, interval=100, blit=True)\n", "\n", "# Note: below is the part which makes it work on Colab\n", "rc('animation', html='jshtml')\n", "anim" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "7MX6yS3rezZH" }, "source": [ "# Reference Link\n", "http://tiao.io/posts/notebooks/embedding-matplotlib-animations-in-jupyter-as-interactive-javascript-widgets/" ] } ], "metadata": { "colab": { "collapsed_sections": [], "include_colab_link": true, "name": "Colab animations.ipynb", "provenance": [] }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.8" } }, "nbformat": 4, "nbformat_minor": 1 }