Uni-Logo
Sie sind hier: Startseite Vorlesungen Höhere Mathematik für Physiker (SS17) Übungen airfoil.py
Artikelaktionen

airfoil.py

airfoil.py — Python Source, 3Kb

Dateiinhalt

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

# Philipp Maierhöfer, 2017

import sys
import os
import argparse

allowed_fileexts = ['.pdf', '.ps', '.eps', '.png', '.svg']

parser = argparse.ArgumentParser(description=
    """Use the Joukowski function to plot an airfoil as the image of a circle
    around z0=-a+i*b and corresponding streamlines. If no output file is
    specified, print the plot on the screen. This only works when the matplotlib
    backend is configured properly (set 'backend' in your matplotlibrc file to
    an available output driver). Requires matplotlib and numpy.""")
parser.add_argument('-o', '--output', dest='outfile', metavar='outfile',
                    default=None,
                    help='output file name, supported file formats are {}'
                         .format(' '.join(allowed_fileexts)))
parser.add_argument('-v', dest='vstep', metavar='vstep', type=float,
                    default=0.1,
                    help='the distance of the streamlines')
parser.add_argument('a', type=float, help='the negative real part of z0')
parser.add_argument('b', type=float, help='the imaginary part of z0')
args = parser.parse_args()

z0 = -args.a + 1j*args.b

if args.outfile:
    fileext = os.path.splitext(args.outfile)[1].lower()
    if fileext not in allowed_fileexts:
        print 'Error: Unsupported file extension \'' + fileext + '\'.'
        print '       Supported formats are', allowed_fileexts
        sys.exit(1)

try:
    import matplotlib
except ImportError:
    print "Error: matplotlib not found."
    sys.exit(1)
import numpy
import matplotlib.pyplot as plt

# List backends
#print matplotlib.rcsetup.all_backends
# Print the current backend
#print matplotlib.get_backend()
# Print the currently used matplotlibrc file path
#print matplotlib.matplotlib_fname()

def hinvpart(z, z0):
    return (z0 + numpy.absolute(1-z0) *
            (z + 1j*numpy.sqrt(1-z**2)*numpy.sign(numpy.imag(z))))

def hinv(x, y, z0):
    return (hinvpart(x+1j*y, z0) + 1/hinvpart(x+1j*y, z0))/2

# a small positive regulator
ep = 0.00001
# the number of points to sample in each curve
npoints = 1000

# prepare the data for the airfoil as a polygon;
# need to reverse one of the data sets
t = numpy.linspace(-1,1,npoints)
airfoil_xdata = numpy.concatenate(
    [numpy.real(hinv(t,ep,z0)), numpy.real(hinv(t,-ep,z0))[::-1]])
airfoil_ydata = numpy.concatenate(
    [numpy.imag(hinv(t,ep,z0)), numpy.imag(hinv(t,-ep,z0))[::-1]])

plotrangex = [min(1.3*min(airfoil_xdata), -1.5),
              max(1.3*max(airfoil_xdata), 1.5)]
plotrangey = [min(1.3*min(airfoil_ydata), -1),
              max(1.3*max(airfoil_ydata), 1)]
plt.figure()
plt.title(u'z₀ = {}{:+}i'.format(-args.a, args.b))
plt.xlim(*plotrangex)
plt.ylim(*plotrangey)
plt.axes().set_aspect('equal')

# draw the streamlines; the range in x direction will be larger than plotrangex
u = numpy.linspace(plotrangex[0], plotrangex[1], npoints)
for vn in range(int((plotrangey[1]-plotrangey[0])/args.vstep)):
    v = plotrangey[0] + vn*args.vstep + ep
    plt.plot(numpy.real(hinv(u,v,z0)),
             numpy.imag(hinv(u,v,z0)),
             linestyle='dotted',
             color='blue')

# draw the airfoil as a filled polygon
plt.fill(airfoil_xdata, airfoil_ydata, color='red')

if args.outfile:
    plt.savefig(args.outfile, format=fileext[1:])
else:
    plt.show()
Benutzerspezifische Werkzeuge