{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Under the hood\nWhat happens behind the scene to compute the wave propagation in rods.\n\nTwo cases are considered:\n\n* :class:`Waveprop` considers a single rod (with section change);\n* :class:`WP2` considers several rods in contact. \n\n:class:`Waveprop` was the first implementation from the work of Bacon 1993. \nIt was kept as it allows faster testing of new features since the computation\nof the state of the bar is done internally, whereas this is done externally \nin the case of :class:`WP2` (see below :class:`Segment`).\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\nimport matplotlib.pyplot as plt\nfrom elwaspatid import Waveprop, WP2, BarSingle, BarSet \n\nE = 210e9  # [MPa]\nrho = 7800  # [kg/m3]\nL = 1  # [m]\nd = 0.02  # [m]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Wave propagation with :class:`Waveprop`\nBar configuration: one bar at rest with an incident wave.\nIndeed, :class:`Waveprop` eats a single :class:`BarSingle` continuous rod and\ncomputes internally the propagation of force and velocity along the rod\nand as time increases. \n\nSince there is no contact interface (single rod), the implementation from \nthe work of Bacon 1993 is straightforward. For each time step:\n1. compute the force and velocity at the left and right ends; \n2. compute the force and velocity in themiddle of the bar  (see :meth:`Waveprop.__init__`).\nAll the force values can fill a single matrix, ditto for the velocities.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "D = np.linspace(0.5, 4, 40)*d  # bar with linearly increasing diamter\nbb = BarSingle(dx=0.01, d=D, E=E, rho=rho)\n\nincw = np.zeros(80)  # incident wave\nincw[0:20] = 1  # >0 means traction pulse\ntest = Waveprop(bb, incw, nstep=2*len(incw), left='free', right='free')\n\ntest.plot()  # plot Force and Velocity space-time diagrams\nbb.plot(typ='DZ')  # plot discretization of the bar and impedance"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. figure:: ../_static/Bacon1993_Figure2.png\n   :scale: 50%\n\n   Discretization of the rod in elements (from [Bacon 1993])\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Wave propagation with :class:`WP2`\n:class:`WP2` allows several rods in contact, which means compression crosses\nthe contact interface whereas traction cannot cross the contact interface and \nis therefore reflected.\n\nSince we consider several rods in contact, the velocity is discontinuous along\nthe propagation axis. Hence, force and velocity cannot be computed globally\nand must be evaluated for each rod. Each rod stores force and velocity in two\nmatrices. \n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Bar configuration: one striker with initial velocity and one bar at rest\nbar = BarSet([E, E], [rho, rho], [L, 0.5*L], [d, 0.8*d], nmin=6)\ntestk = WP2(bar, nstep=200, left='free', right='infinite', Vinit=5)\ntestk.plot()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Internally, the bar :class:`BarSet` contains a list of :class:`Segment`, one\nfor each independant rod. Each :class:`Segment` has been discretized in ``nX``\nelements along the propagation axis.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(bar.seg)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ":class:`Segment` has the following methods:\n\n- :meth:`Segment.initCalc`\n- :meth:`Segment.compMiddle`\n- :meth:`Segment.compLeft`\n- :meth:`Segment.compRight`\n\nThese methods are called by :meth:`WP2.__init__` which, while looping over time,\niterates on all the :class:`Segment` in the list provided by :class:`BarSet` to\ncompute the state (Force, Velocity) of all the elements of each :class:`Segment`.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ":class:`Bar` is used to store and plot the evolution of the properties \ngiven to :class:`BarSet` at instantiation (in :attr:`BarSet.bar_continuous`)\nBe carfeul, afterwards modifications with :meth:`BarSet.changeSection` do not \naffect :class:`Bar`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "bar.bar_continuous.plot()\nplt.show()"
      ]
    }
  ],
  "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.6.15"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}