{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Lateral advection\n", "\n", "PyLag can be easily used with analytical models of different flow fields. This provides a convenient means of testing\n", "the model implementation. The example described here is taken from Kreyszig, E. (2006) Advanced Engineering\n", "Mathematics, Ch. 18. P762.\n", "\n", "## Background theory\n", "\n", "In the example, the complex potential with $F(z) = z^{2} = x^{2} - y^{2} + 2ixy$ models a flow with equipotential lines and streamlines given by:\n", "\n", "$$\n", "\\begin{eqnarray}\n", " \\Phi &=& x^2 - y^2 &=& const \\\\\n", " \\Psi &=& 2xy &=& const\n", "\\end{eqnarray}\n", "$$ \n", "\n", "The velocity vector is:\n", "\n", "$$\n", "\\begin{equation}\n", " \\mathbf{u} = 2(x - iy)\n", "\\end{equation}\n", "$$\n", "\n", "with components:\n", "\n", "$$\n", "\\begin{eqnarray}\n", " u &=& &2&x \\\\\n", " v &=& -&2&y\n", "\\end{eqnarray}\n", "$$\n", "\n", "The speed of the flow is given by:\n", "\n", "$$\n", "\\begin{equation}\n", " |\\mathbf{u}| = \\sqrt{x^2 + y^2}\n", "\\end{equation}\n", "$$\n", "\n", "The flow may be interpreted as the flow in a channel bounded by the positive coordinate axes and a hyperbola, given by $xy = const$. To calculate particle trajectiories, PyLag solves the equation:\n", "\n", "$$\n", "\\begin{equation}\n", "\\label{eqn:partmotion}\n", " \\dfrac{\\partial}{\\partial t} \\mathbf{X}_{i}(t, \\mathbf{r}_{i}) = \\mathbf{U}_{i}(t, \\mathbf{X}_{i})\n", "\\end{equation}\n", "$$\n", "\n", "where $\\mathbf{r}_{i} = \\mathbf{X}_i(t=t_0)$ is the position vector of particle $i$ at time $t=t_{0}$, and $\\mathbf{U}_{i}$ is the particle's velocity vector. Here, $\\mathbf{U}_{i} = [\\mathbf{u}(t, \\mathbf{x})]_{\\mathbf{x} = \\mathbf{X}_{i}}$ where $\\mathbf{u}$ is the fluid velocity vector, as given above.\n", "\n", "In practise, *PyLag* computes solutions to the above equation using a Random Displacement Model of the form:\n", "\n", "$$\n", "\\begin{equation}\n", " dX_{j} = \\left[u_{j}\\left(\\mathbf{x},t\\right) + \\dfrac{\\partial D_{jk}\\left(\\mathbf{x},t\\right)}{\\partial x_{k}}\\right]dt + \\left(2 D_{jk}\\left(\\mathbf{x},t\\right)\\right)^{1/2}dW_{k}(t)\n", "\\end{equation}\n", "$$\n", "\n", "Here, $dX_{j} = d\\mathbf{X}$ is the incremental change in a particle's position and $D_{jk}$ is the diffusion coefficient or tensor. The first term on the right-hand side (RHS) of the equation is a deterministic drift term; the second is a stochastic term that models the action of diffusion. $dW_{j}(t)$ is an incremental Wiener process that builds stochasticity into the model.\n", "\n", "In this particular problem, the diffusion coefficient is zero. In component form, the model then reduces to:\n", "\n", "$$\n", "\\begin{equation}\n", "\\label{eqn:dx}\n", " dX = u\\left(\\mathbf{x},t\\right) dt,\n", "\\end{equation}\n", "$$\n", "\n", "$$\n", "\\begin{equation}\n", "\\label{eqn:dy}\n", " dY = v\\left(\\mathbf{x},t\\right) dt,\n", "\\end{equation}\n", "$$\n", "\n", "$$\n", "\\begin{equation}\n", "\\label{eqn:dz}\n", " dZ = 0,\n", "\\end{equation}\n", "$$\n", "\n", "which can be solved using one of the standard numerical integration schemes supported by *PyLAg*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Running the particle tracking model\n", "\n", "To compute particle trajectories within the given flow field using *PyLag*, we first subclass *PyLag's* `DataReader`. The new subclass must be implemented in *Cython*, since several of its functions have arguments without a direct counterpart in Python. The above model has been implemented in `pylag.mock`, and is called `MockVelocityDataReader`.\n", "\n", "