{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "<!-- dom:TITLE: Example on interactive live documents versus traditional static documents -->\n",
    "# Example on interactive live documents versus traditional static documents\n",
    "**hpl**\n",
    "\n",
    "Date: **Apr 15, 2021**\n",
    "\n",
    "## Physics\n",
    "<div id=\"ipynbex:physics\"></div>\n",
    "\n",
    "We consider a vibrating mechanical system as shown in [Figure 1](#ipynbex:physics:fig).\n",
    "\n",
    "<!-- dom:FIGURE: [../doc/src/ipynb/fig/oscillator_general.png, width=600 frac=0.8] Oscillating system with spring and damper. <div id=\"ipynbex:physics:fig\"></div> -->\n",
    "<!-- begin figure -->\n",
    "<div id=\"ipynbex:physics:fig\"></div>\n",
    "\n",
    "<img src=\"../doc/src/ipynb/fig/oscillator_general.png\" width=600><p style=\"font-size: 0.9em\"><i>Figure 1: Oscillating system with spring and damper.</i></p>\n",
    "<!-- end figure -->\n",
    "\n",
    "## Mathematics\n",
    "<div id=\"ipynbex:math\"></div>\n",
    "\n",
    "A differential equation for the system in [Figure 1](#ipynbex:physics:fig) reads"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "$$\n",
    "mu'' + f(u') + s(u) = F(t),\\quad u(0)=I,\\ u'(0)=V\\thinspace .\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "In the linear damping case, where $f(u')=bu'$ for some constant\n",
    "$b\\geq 0$, we can solve the problem numerically by a scheme"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "<!-- Equation labels as ordinary links -->\n",
    "<div id=\"ipynbex:u:scheme:lin\"></div>\n",
    "\n",
    "$$\n",
    "\\begin{equation}\n",
    "u^{n+1} = \\left(2mu^n + (\\frac{b}{2}\\Delta t - m)u^{n-1} +\n",
    "\\Delta t^2(F^n - s(u^n))\n",
    "\\right)(m + \\frac{b}{2}\\Delta t)^{-1},\n",
    "\\label{ipynbex:u:scheme:lin} \\tag{1}\n",
    "\\end{equation}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "for $n=0,1,\\ldots$. A special formula is required for $n=0$:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "<!-- Equation labels as ordinary links -->\n",
    "<div id=\"ipynbex:u:scheme0:lin\"></div>\n",
    "\n",
    "$$\n",
    "\\begin{equation}\n",
    "u^1 = u^0 + \\Delta t\\, V\n",
    "+ \\frac{\\Delta t^2}{2m}(-bV - s(u^0) + F^0)\n",
    "\\thinspace .\n",
    "\\label{ipynbex:u:scheme0:lin} \\tag{2}\n",
    "\\end{equation}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "## Implementation\n",
    "\n",
    "<!-- Note: Plain Markdown cannot refer to equations with numbers. -->\n",
    "<!-- This is a DocOnce extension. -->\n",
    "\n",
    "The formulas ([1](#ipynbex:u:scheme:lin)) and ([2](#ipynbex:u:scheme0:lin))\n",
    "can be implemented as follows in a Python function:\n",
    "\n",
    "<!-- Next code (hidden code): -->\n",
    "<!-- Not strictly needed since zeros inside the next function -->\n",
    "<!-- is not called before the main program has imported zeros... -->\n",
    "<!-- But in general one may need special imports for the next -->\n",
    "<!-- code segments to execute properly. -->"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "from numpy import zeros"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def solver_linear_damping(I, V, m, b, s, F, t):\n",
    "    N = t.size - 1              # No of time intervals\n",
    "    dt = t[1] - t[0]            # Time step\n",
    "    u = zeros(N+1)              # Result array\n",
    "    u[0] = I\n",
    "    u[1] = u[0] + dt*V + dt**2/(2*m)*(-b*V - s(u[0]) + F[0])\n",
    "\n",
    "    for n in range(1,N):\n",
    "        u[n+1] = 1./(m + b*dt/2)*(2*m*u[n] + \\\n",
    "                 (b*dt/2 - m)*u[n-1] + dt**2*(F[n] - s(u[n])))\n",
    "    return u"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "## Dissection\n",
    "\n",
    "<!-- Code here is not meant to be executed, just shown for discussion. -->\n",
    "\n",
    "The array `t` holds all the time points where we want a solution.\n",
    "The total number of intervals, $N$, is then computed as"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "```Python\n",
    "        N = t.size - 1   # or len(t) - 1\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "Creating an array of length $N+1$ where we can store the solution\n",
    "is done by"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "```Python\n",
    "        u = zeros(N+1)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "For loops over array indices are coded as"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "```Python\n",
    "        for n in range(1, N):\n",
    "            ...\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "which generates a sequence of integers from 1 up to `N`, *but not\n",
    "including* `N`.\n",
    "\n",
    "## Usage\n",
    "\n",
    "The function `solve_linear_damping` resides in a file `solver.py`.\n",
    "\n",
    "<!-- Need to tell where solver.py is for the notebook to execute properly. -->\n",
    "<!-- For this we use a hidden python code (pyhid). It will be hidden -->\n",
    "<!-- in all formats, except in the notebook. -->"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# The solver module is in src/solver.py; tell Python about that\n",
    "import sys\n",
    "sys.path.insert(0, 'src')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "editable": true
   },
   "source": [
    "<!-- For matplotlib we need to insert %matplotlib inline in the notebook. -->\n",
    "<!-- (Automatically done by DocOnce.) -->"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "from solver import solver_linear_damping\n",
    "from numpy import linspace, zeros, pi\n",
    "\n",
    "def s(u):\n",
    "    return 2*u\n",
    "\n",
    "T = 10*pi      # simulate for t in [0,T]\n",
    "dt = 0.2\n",
    "N = int(round(T/dt))\n",
    "t = linspace(0, T, N+1)\n",
    "F = zeros(t.size)\n",
    "I = 1; V = 0\n",
    "m = 2; b = 0.2\n",
    "u = solver_linear_damping(I, V, m, b, s, F, t)\n",
    "\n",
    "from matplotlib.pyplot import *\n",
    "plot(t, u)\n",
    "show()"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 4
}
