{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Inspired by https://perso.ensta-paris.fr/~becache/COURS-ONDES/Poly-num-0209.pdf" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "\\frac{u_{ij}^{n+1} - 2u_{ij}^{n} + u_{ij}^{n-1}}{\\Delta t^2} - \\frac{u_{i+1j}^{n} - 2u_{ij}^{n} + u_{i-1j}^{n}}{\\Delta x^2} - \\frac{u_{ij+1}^{n} - 2u_{ij}^{n} + u_{ij-1}^{n}}{\\Delta x^2} = g(n\\Delta t) f(x_i, y_j)\n", "$$\n", "\n", "Rearranging for explicit terms, we get:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import holoviews as hv\n", "hv.extension('bokeh', logo=False)\n", "\n", "import numba\n", "import numpy as np\n", "\n", "@numba.jit\n", "def step(U, V, W, dt, dx, dy, g, t, f):\n", " \"\"\"U = u^n+1, V = u^n, W = u^n-1.\"\"\"\n", " N, M = U.shape\n", " for i in range(1, N-1):\n", " for j in range(1, M-1):\n", " U[i, j] = dt**2 / dx ** 2 * (V[i+1, j] - 2 * V[i, j] + V[i-1, j]) + \\\n", " dt**2 / dy ** 2 * (V[i, j+1] - 2 * V[i, j] + V[i, j-1]) + \\\n", " dt**2 * g(t) * f(i * dx, j * dy) + \\\n", " 2 * V[i, j] - W[i, j] \n", " return U\n", "\n", "\n", "\n", "@numba.jit\n", "def g(t):\n", " return np.sin(2 * np.pi * 15e-2 * t)\n", "\n", "@numba.jit\n", "def f(x, y):\n", " x0, y0 = (62.5, 32.5)\n", " return np.exp(- np.abs((x - x0)**2 + (y - y0)**2))\n", "\n", "def n_steps(U, V, W, dt, dx, dy, g, t0, f, nsteps=100):\n", " for i in range(nsteps):\n", " t = t0 + i * dt\n", " U = step(U, V, W, dt, dx, dy, g, t, f)\n", " W = V.copy()\n", " V = U.copy()\n", " return U, V, W, t" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "N, M = 250, 260\n", "U = np.zeros((N, M))\n", "V = np.zeros((N, M))\n", "W = np.zeros((N, M))\n", "dt = 0.1\n", "dx = 0.5\n", "dy = dx\n", "t = 0" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "N * dx / 2, M * dy / 4" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "snapshots = []\n", "for _ in range(30):\n", " U, V, W, t = n_steps(U, V, W, dt, dx, dy, g, t, f, nsteps=50)\n", " snapshots.append(U.copy())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%output holomap='scrubber'\n", "hv.HoloMap({ind: hv.Image(U.T).opts(cmap='seismic', tools=['hover'], colorbar=True, width=700, height=600).redim.range(z=(-1e-1, 1e-1)) for ind, U in enumerate(snapshots)})" ] } ], "metadata": { "kernelspec": { "display_name": "Python 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.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }