{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Doinikov 2021 Viscous - Convergence Study\n\nIn this example we use the model ``doinikov2021viscous``. For the\ncomputation of the ARF the acoustic field is integrated from the surface of\nthe particle to infinity. \"Infinity\" here means a point far away from the\nparticle where the acoustic field is no longer influenced by its presence. Our\nquadrature method [scipy.integrate.quad](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.quad.html)\noffers the option to integrate to infinity for converging functions.\nHowever, for the given integral this does not work reliably. We therefore\nchoose the distance far away from the particle ourselves. In this example it is\nshown how.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "In this example we study a glass sphere viscous fluid.\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\n\n# --------\n# Geometry\n# --------\n# Radius\nR_0 = 1e-6  # [m]\n\n# --------------------\n# Properties of Glass\n# --------------------\n# Speed of sound\nc_1_glass = 4_521  # [m/s]\nc_2_glass = 2_226  # [m/s]\n# Density\nrho_glass = 2_240  # [kg/m^3]\n\n# -----------------\n# Properties of Oil\n# -----------------\n# Speed of sound\nc_oil = 1_400  # [m/s]\n# Density\nrho_oil = 900  # [kg/m^3]\n# Viscosity\neta_oil = 0.04  # [Pa s]\nzeta_oil = 0  # [Pa s]\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": [
        "Here, we are given the primary and the secondary wave speed of\nglass only. The model ``doinikov2021viscous``, however, takes the Young's\nmodulus and the Poisson's ratio as input parameters. We therefore have to\nconvert the properties. The ``ElasticSolid`` class offers such conversion\nmethods.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "E_s = osaft.ElasticSolid.E_from_wave_speed(c_1_glass, c_2_glass, rho_glass)\nnu_s = osaft.ElasticSolid.nu_from_wave_speed(c_1_glass, c_2_glass)\n\ndoinikov_viscous = osaft.doinikov2021viscous.ARF(\n    f=f,\n    R_0=R_0,\n    rho_s=rho_glass,\n    E_s=80e9,\n    nu_s=0.20,\n    rho_f=rho_oil,\n    c_f=c_oil,\n    eta_f=eta_oil,\n    zeta_f=zeta_oil,\n    p_0=p_0,\n    wave_type=wave_type,\n    position=position,\n    inf_factor=60,\n    inf_type=None,\n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We could now straightaway compute the ARF with the model. And for most\ncases this will work just fine. However, if you need to be extra sure that\nthe integral has been solved accurately you might want to make a\nconversion study for the value of \"infinity\". By default, this value\nis set to $60\\max{(R_0,\\delta)}$. That is, it is set\nto 60 times the boundary layer thickness or the radius, whichever is greater.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(f\"{doinikov_viscous.R_0 = }\")\nprint(f\"{doinikov_viscous.delta = }\")\nprint(f\"{doinikov_viscous.inf_factor = }\")\nprint(f\"{doinikov_viscous.inf = }\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The value of ``inf`` can also be set manually using the two parameters\n``inf_factor`` and ``inf_type``. ``inf_factor`` is the prefactor for\n``inf_type`` and should be a numerical value. For ``inf_type`` there are 4\noptions:\n\n - ``None``: $\\text{inf_factor}\\cdot\\max{(R_0,\\delta)}$\n - ``'delta'``: the boundary layer thickness $\\delta$\n - ``'radius'``: the radius $\\delta$\n - ``1`` or ``'1'``: ``inf`` is simply the ``inf_factor``\n\nUsually leaving it at ``None`` is the best option.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "doinikov_viscous.inf_type = 1\ndoinikov_viscous.inf_factor = 1e-4\nprint(f\"{doinikov_viscous.inf_factor = }\")\nprint(f\"{doinikov_viscous.inf_type = }\")\nprint(f\"{doinikov_viscous.inf = }\")\ndoinikov_viscous.inf_type = \"radius\"\ndoinikov_viscous.inf_factor = 60\nprint(f\"{doinikov_viscous.inf_factor = }\")\nprint(f\"{doinikov_viscous.inf_type = }\")\nprint(f\"{doinikov_viscous.inf = }\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Often it is not apriori clear what value should be chosen. Therefore,\na convergence study can be performed. The plotting functionality of OSAFT\ncan be very handy for this since we can plot the ARF against the\n``inf_factor``.\n\nIn order for multiprocessing to work you need to run your code inside the\n``if __name__ == '__main__':`` clause as shown below.\nCheck the `multiprocessing example\n<sphx_glr_examples_tutorial_example_multicore.py>`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "if __name__ == \"__main__\":\n\n    doinikov_viscous.inf_type = None\n    plot = osaft.ARFPlot(\"inf_factor\", np.arange(10, 200, 30))\n    plot.add_solutions(doinikov_viscous, multicore=True)\n    fig, ax = plot.plot_solutions(normalization=\"max\", marker=\"o\")\n\n    ax.set_xlabel(\"inf_factor\")\n    ax.ticklabel_format(useOffset=False)\n    fig.tight_layout()\n    plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We see that already for a value of ``inf_factor`` of 40 the ARF stops\nchanging significantly. In fact, going from ``inf_factor = 40`` to\n``inf_factor = 200`` will change the value of the ARF less than 0.001%.\nThis will be sufficiently accurate for most cases. Note that this also means\nfor the  given example the default settings would give a very accurate\nestimate of the ARF.\n\n"
      ]
    }
  ],
  "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
}