{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Frontiers: Air Bubble in Water\n\nThis example corresponds to section 3.4 in\n`our publication <CitingOsaft>`.\nIn this example we study the acoustic radiation force (ARF) on an air bubble\nsuspended in water.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "As always we start off by importing the necessary Python modules. For our\nexample we are going to need the osaft library, and the third party packages\nNumPy and Matplotlib.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\nfrom matplotlib import pyplot as plt\n\nimport osaft"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The next step is to define the properties for our example,\nthese include the material properties, the properties of the acoustic field\nand the radius. We always assume SI-units.\n\nThe wave type is set using the ``osaft.WaveType`` enum. Currently, there are\ntwo options:\n``osaft.WaveType.STANDING`` and ``osaft.WaveType.TRAVELLING`` for a plane\nstanding wave and a plane travelling wave, respectively.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# --------\n# Geometry\n# --------\n# Radius\nR_0 = 5e-6  # [m]\n\n# -----------------\n# Properties of Air\n# -----------------\n# Speed of sound\nc_air = 343  # [m/s]\n# Density\nrho_air = 1.225  # [kg/m^3]\n\n# -------------------\n# Properties of Water\n# -------------------\n# Speed of sound\nc_w = 1_498  # [m/s]\n# Density\nrho_w = 997  # [kg/m^3]\n\n# --------------------------------\n# Properties of the Acoustic Field\n# --------------------------------\n# Frequency\nf = 5e5  # [Hz]\n# Pressure\np_0 = 1e5  # [Pa]\n# Wave type\nwave_type = osaft.WaveType.STANDING\n# Position of the particle in the field\nposition = np.pi / 4  # [rad]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Once all properties are defined we can initialize the solution instances.\n``osaft.yosioka1995.ARF()`` is the class for computing the ARF using the\nmodel by Yosioka and Kawasima (1955).\n\nHere we give the instances different names ``'General'`` and ``'Bubble'``\nby setting the ``name`` attribute.\nThis makes sure we can later distinguish them when the solutions are plotted.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# General\nyosioka = osaft.yosioka1955.ARF(\n    f=f,\n    R_0=R_0,\n    rho_s=rho_air,\n    c_s=c_air,\n    rho_f=rho_w,\n    c_f=c_w,\n    p_0=p_0,\n    wave_type=wave_type,\n    position=position,\n)\nyosioka.name = \"General\"\n\n# Small bubble approximation\nyosioka_bubble = yosioka.copy()\nyosioka_bubble.small_particle = True\nyosioka_bubble.bubble_solution = True\nyosioka_bubble.name = \"Bubble\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "With the class ``osaft.yosioka1955.ARF()`` it is also possible to plot the\nacoustic fields. Here, we first set the frequency to ``6.5e5`` Hz.\nThen we initialize a ``osaft.FluidScatteringPlot()`` instance which will plot\nthe acoustic field in the fluid. The class takes the model as an argument\nand the radius range ``r_max`` that is plotted. For more option see the\ndocumentation.\n\nThe method ``plot()`` will then generate the plot.\nAs always with Matplotlib, we need to call ``plt.show()`` to display it.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Setting frequency close to resonance\nyosioka.f = 6.5e5\n\n# Initializing plotting class\nscattering_plot = osaft.FluidScatteringPlot(yosioka, r_max=3 * yosioka.R_0)\n\n# Plot scattering field\nfig, ax = scattering_plot.plot_velocity()\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "To animate the acoustic field we can call the method\n``animate()``. Setting\n``incident = False`` means that we are only animating the scattered field\nbut not the incident field.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "anim = scattering_plot.animate_velocity(\n    frames=20,\n    interval=100,\n    incident=False,\n)\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, we want to compare the general solution for the ARF\nwith the approximate solution for a bubble. To plot the ARF\nwe need to initialize ``osaft.ARFPlot()`` instance. With the method\n``add_solutions()`` we can add our models to the plotter.\nWith ``set_abscissa()`` we define the variable that we want to\nplot the ARF against. Here we select the frequency ``f``.\nFinally, ``osaft.ARFPlot.plot_solutions()`` will generate the plot. Again,\nwe call ``plt.show()`` to display it.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# sphinx_gallery_thumbnail_number = -1\n# Initializing plotting class\narf_plot = osaft.ARFPlot()\n\n# Add solutions to be plotted\narf_plot.add_solutions(yosioka, yosioka_bubble)\n\n# Define independent plotting variable (in this case the frequency)\narf_plot.set_abscissa(x_values=np.linspace(1e5, 1e6, 300), attr_name=\"f\")\n\n# Plot the ARF\nfig, ax = arf_plot.plot_solutions()\n\n# Setting the axis labels\nax.set_xlabel(r\"$f$ $\\mathrm{[Hz]}$\")\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "<div class=\"alert alert-info\"><h4>Note</h4><p>It is only possible to plot the ARF  against\n      properties that wrap an underlying ``PassiveVariable``, i.e. an input\n      parameter of the model.\n      You can get a list of all input variables using the method\n      ``input_variables()``.</p></div>\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(f\"{yosioka.input_variables() = }\")"
      ]
    }
  ],
  "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.9.15"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}