{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Streamlines {#streamlines_example}\n\nIntegrate a vector field to generate streamlines.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This example generates streamlines of blood velocity. An isosurface of\nspeed provides context. The starting positions for the streamtubes were\ndetermined by experimenting with the data.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\n\nimport pyvista as pv\nfrom pyvista import examples"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Carotid\n\nDownload a sample dataset containing a vector field that can be\nintegrated.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh = examples.download_carotid()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Run the stream line filtering algorithm using random seed points inside\na sphere with radius of 2.0.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "streamlines, src = mesh.streamlines(\n    return_source=True,\n    max_time=100.0,\n    initial_step_length=2.0,\n    terminal_speed=0.1,\n    n_points=25,\n    source_radius=2.0,\n    source_center=(133.1, 116.3, 5.0),\n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Display the results. Please note that because this dataset\\'s velocity\nfield was measured with low resolution, many streamlines travel outside\nthe artery.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "p = pv.Plotter()\np.add_mesh(mesh.outline(), color=\"k\")\np.add_mesh(streamlines.tube(radius=0.15))\np.add_mesh(src)\np.add_mesh(mesh.contour([160]).extract_all_edges(), color=\"grey\", opacity=0.25)\np.camera_position = [(182.0, 177.0, 50), (139, 105, 19), (-0.2, -0.2, 1)]\np.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Blood Vessels\n\nHere is another example of blood flow:\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh = examples.download_blood_vessels().cell_data_to_point_data()\nmesh.set_active_scalars(\"velocity\")\nstreamlines, src = mesh.streamlines(\n    return_source=True,\n    source_radius=10,\n    source_center=(92.46, 74.37, 135.5),\n)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "boundary = mesh.decimate_boundary().extract_all_edges()\n\nsargs = dict(vertical=True, title_font_size=16)\np = pv.Plotter()\np.add_mesh(streamlines.tube(radius=0.2), lighting=False, scalar_bar_args=sargs)\np.add_mesh(src)\np.add_mesh(boundary, color=\"grey\", opacity=0.25)\np.camera_position = [(10, 9.5, -43), (87.0, 73.5, 123.0), (-0.5, -0.7, 0.5)]\np.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "A source mesh can also be provided using the\n`pyvista.DataSetFilters.streamlines_from_source`{.interpreted-text\nrole=\"func\"} filter, for example if an inlet surface is available. In\nthis example, the inlet surface is extracted just inside the domain for\nuse as the seed for the streamlines.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "source_mesh = mesh.slice('z', origin=(0, 0, 182))  # inlet surface\n# thin out ~40% points to get a nice density of streamlines\nseed_mesh = source_mesh.decimate_boundary(0.4)\nstreamlines = mesh.streamlines_from_source(seed_mesh, integration_direction=\"forward\")\n# print *only* added arrays from streamlines filter\nprint(\"Added arrays from streamlines filter:\")\nprint([array_name for array_name in streamlines.array_names if array_name not in mesh.array_names])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Plot streamlines colored by the time along the streamlines.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "sargs = dict(vertical=True, title_font_size=16)\np = pv.Plotter()\np.add_mesh(\n    streamlines.tube(radius=0.2),\n    scalars=\"IntegrationTime\",\n    clim=[0, 1000],\n    lighting=False,\n    scalar_bar_args=sargs,\n)\np.add_mesh(boundary, color=\"grey\", opacity=0.25)\np.add_mesh(source_mesh, color=\"red\")\np.camera_position = [(10, 9.5, -43), (87.0, 73.5, 123.0), (-0.5, -0.7, 0.5)]\np.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Kitchen\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "kpos = [(-6.68, 11.9, 11.6), (3.5, 2.5, 1.26), (0.45, -0.4, 0.8)]\n\nmesh = examples.download_kitchen()\nkitchen = examples.download_kitchen(split=True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "streamlines = mesh.streamlines(n_points=40, source_center=(0.08, 3, 0.71))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "p = pv.Plotter()\np.add_mesh(mesh.outline(), color=\"k\")\np.add_mesh(kitchen, color=True)\np.add_mesh(streamlines.tube(radius=0.01), scalars=\"velocity\", lighting=False)\np.camera_position = kpos\np.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Custom 3D Vector Field\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nx = 20\nny = 15\nnz = 5\n\norigin = (-(nx - 1) * 0.1 / 2, -(ny - 1) * 0.1 / 2, -(nz - 1) * 0.1 / 2)\nmesh = pv.ImageData(dimensions=(nx, ny, nz), spacing=(0.1, 0.1, 0.1), origin=origin)\nx = mesh.points[:, 0]\ny = mesh.points[:, 1]\nz = mesh.points[:, 2]\nvectors = np.empty((mesh.n_points, 3))\nvectors[:, 0] = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)\nvectors[:, 1] = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)\nvectors[:, 2] = np.sqrt(3.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) * np.sin(np.pi * z)\n\nmesh['vectors'] = vectors"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "stream, src = mesh.streamlines(\n    'vectors',\n    return_source=True,\n    terminal_speed=0.0,\n    n_points=200,\n    source_radius=0.1,\n)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "cpos = [(1.2, 1.2, 1.2), (-0.0, -0.0, -0.0), (0.0, 0.0, 1.0)]\nstream.tube(radius=0.0015).plot(cpos=cpos)"
      ]
    }
  ],
  "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.12.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}