Consider a 2D vortex sheet defined along a curve $\cal S$. The sheet is characterized by a *strength* $\gamma(s)$, where $s$ is the coordinate along the sheet. An infinitesimal segment of this sheet is an infinitesimal point-vortex with strength $d\Gamma = \gamma ds$. Therefore we can integrate the potential for a point vortex

to define the potential function for a vortex sheet as

$$ \phi(x,y) = \int_{\cal S} \frac{\gamma(s)}{2\pi}\theta(x,y,s)\ ds $$where $\theta$ is the angle from $s$ to the point at which we evaluate the potential.

For a vortex sheet defined from $-S,S$ along the $x$-axis, $\theta=\tan^{-1}(y/(x-s))$. If the strength is constant along the sheet, the potential is

$$ \phi(x,y) = \frac{\gamma}{2\pi}\int^S_{-S} \tan^{-1}\left(\frac y{x-s}\right)ds $$The velocity is defined from the potential as

$$ u = \frac{\partial\phi}{\partial x}, \quad v = \frac{\partial\phi}{\partial y} $$Therefore, the $u$ velocity is

$$u(x,y) = \frac{\gamma}{2\pi}\int^S_{-S} \frac{-y}{y^2+(x-s)^2} ds $$substitute $t = (x-s)/y$, $dt = -ds/y$ and integrate to get

$$u(x,y) = \frac{\gamma}{2\pi}\left[\tan^{-1}\left(\frac{x-S}y\right)-\tan^{-1}\left(\frac{x+S}y\right)\right].$$While the $v$ velocity is

$$v(x,y) = \frac{\gamma}{2\pi}\int^S_{-S} \frac{x-s}{y^2+(x-s)^2} ds $$substitute $t = (x-s)^2+y^2$, $dt = -2(x-s)ds$ and integrate to get

$$v(x,y) =\frac{\gamma}{4\pi} \log\left(\frac{(x+S)^2+y^2}{(x-S)^2+y^2}\right).$$That's it! For a given $\gamma$ and $S$ we can determine the velocity at any point $x,y$ by evaluating some $\tan^{-1}$ and $\log$ functions.

To visualize the velocity field we will discretize the background space into a uniform grid and evaluate the functions above at each point.

We need to `import numpy`

to do this. This imports numerical functions like `linspace`

to evenly divide up a line segment into an array points, and `meshgrid`

which takes two one-dimensional arrays and creates two two-dimensional arrays to fill the space.

```
In [1]:
```import numpy
N = 30 # number of points along each axis
X = numpy.linspace(-2, 2, N) # computes a 1D-array for x
Y = numpy.linspace(-2, 2, N) # computes a 1D-array for y
x, y = numpy.meshgrid(X, Y) # generates a mesh grid

`import pyplot`

which has a large set of plotting functions similar to matlab, such as a scatter plot.

```
In [2]:
```from matplotlib import pyplot
%matplotlib inline
pyplot.scatter(x, y)
pyplot.xlabel('x')
pyplot.ylabel('y')

```
Out[2]:
```

As expected, a grid of equally space points.

Next, we use the equations above to determine the velocity at each point in terms of the source strength and sheet extents. Since we'll use this repeatedly, we will write it as a set of functions.

If you aren't familiar with defining functions in python, read up.

```
In [3]:
```# velocity component functions
def get_u( x, y, S, gamma ):
return gamma/(2*numpy.pi)*(numpy.arctan((x-S)/y)-numpy.arctan((x+S)/y))
def get_v( x, y, S, gamma ):
return gamma/(4*numpy.pi)*(numpy.log(((x+S)**2+y**2)/((x-S)**2+y**2)))

Not the prettiest equations, but nothing `numpy`

can't handle.

Now let's make a function to plot the flow. We'll use arrows to show the velocity vectors (`quiver`

) and color contours to show the velocity magnitude (`contourf`

with `colorbar`

for the legend).

I've also included the `streamplot`

function to plot streamlines, but this is slow, so I'll let you turn it on your self if you want them.

```
In [4]:
```def plot_uv(u,v):
pyplot.figure(figsize=(8,11)) # set size
pyplot.xlabel('x', fontsize=16) # label x
pyplot.ylabel('y', fontsize=16) # label y
m = numpy.sqrt(u**2+v**2) # compute velocity magnitude
velocity = pyplot.contourf(x, y, m, vmin=0) # plot magnitude contours
cbar = pyplot.colorbar(velocity, orientation='horizontal')
cbar.set_label('Velocity magnitude', fontsize=16);
pyplot.quiver(x, y, u, v) # plot vector field
# pyplot.streamplot(x, y, u, v) # plots streamlines - this is slow!

Now we can compute the velocity on the grid and plot it

```
In [5]:
```# compute the velocity
gamma = -4 # sheet strength
S = 1 # sheet extents
u = get_u(x,y,S,gamma)
v = get_v(x,y,S,gamma)
# plot it
plot_uv(u,v)
pyplot.plot([-min(S,2),min(S,2)],[0,0],'k-',lw=2) # draw the vortex sheet

```
Out[5]:
```

```
In [4]:
```alpha = numpy.pi/10 # free-stream angle
U_inf = numpy.cos(alpha) # free-stream in x
V_inf = numpy.sin(alpha) # free-stream in y
# superimpose to get velocity
gamma = -4 # sheet strength
S = 0.5 # sheet extents
u = U_inf+get_u(x,y,S,gamma)
v = V_inf+get_v(x,y,S,gamma)
# plot it
plot_uv(u,v)
pyplot.plot([-min(S,2),min(S,2)],[0,0],'k-',lw=2) # draw the vortex sheet

```
```

The dark blue circle is a stagnation point, ie the fluid has stopped, ie $u=v=0$.

Finally, we would like to be able to compute the flow induced by a flat vortex sheet defined between any two points $x_0,y_0$ and $x_1,y_1$. A sheet so defined is called a *vortex panel*. We could start from scratch, re-deriving the potential and velocity fields. But why would we want to do that?

By switching from the global coordinates to a *panel-based* coordinate system, we can transform any vortex panel to match our previous example. After computing the velocity using our old functions, we just need to rotate the vector back to the global coordinates.

The `velocity`

function below follows this process to compute the velocity induced by the panel at any point $x,y$.

We've defined a `class`

called `Panel`

to hold the `velocity`

, `transform_xy`

and `rotate_uv`

functions since these all belong together. This also lets us store the information about a `Panel`

(the end points, strength, width, and direction) using the `__init__`

function, and draw the `Panel`

using the `plot`

function. If you're interested, read up on classes in Python.

```
In [7]:
```# vortex panel class
class Panel:
# save the inputs and pre-compute factors for the coordinate tranform
def __init__( self, x0, y0, x1, y1, gamma ):
self.x,self.y,self.gamma = [x0,x1],[y0,y1],gamma
self.xc = 0.5*(x0+x1) # panel x-center
self.yc = 0.5*(y0+y1) # panel y-center
self.S = numpy.sqrt( # ...
(x1-self.xc)**2+(y1-self.yc)**2) # panel width
self.sx = (x1-self.xc)/self.S # unit vector in x
self.sy = (y1-self.yc)/self.S # unit vector in y
# get the velocity!
def velocity( self, x, y ):
gamma = self.gamma
xp,yp = self.transform_xy( x, y ) # transform
up = get_u( xp, yp, self.S, gamma ) # get u prime
vp = get_v( xp, yp, self.S, gamma ) # get v prime
return self.rotate_uv( up, vp ) # rotate back
# plot the panel
def plot(self):
return pyplot.plot(self.x,self.y,'k-',lw=2)
# transform from global to panel coordinates
def transform_xy( self, x, y ):
xt = x-self.xc # shift x
yt = y-self.yc # shift y
xp = xt*self.sx+yt*self.sy # rotate x
yp = yt*self.sx-xt*self.sy # rotate y
return [ xp, yp ]
# rotate velocity back to global coordinates
def rotate_uv( self, up, vp):
u = up*self.sx-vp*self.sy # reverse rotate u prime
v = vp*self.sx+up*self.sy # reverse rotate v prime
return [ u, v ]

Now we can define a general panel and compute its velocity.

```
In [8]:
```# define panel
my_panel = Panel(x0=-0.7,y0=0.5,x1=0.5,y1=-0.4,gamma=-2)
# compute velocity on grid
u,v = my_panel.velocity(x,y)
# plot it
plot_uv(u,v) # plot the flow on the grid
my_panel.plot() # plot the panel

```
Out[8]:
```

```
In [9]:
``````
# your code here
```

Ignore the line below - it just loads the style sheet.

```
In [10]:
```from IPython.core.display import HTML
def css_styling():
styles = open('../styles/custom.css', 'r').read()
return HTML(styles)
css_styling()

```
Out[10]:
```