SIAM Workshop Introduction to Python for mathematicians...

Post on 06-Mar-2020

9 views 0 download

Transcript of SIAM Workshop Introduction to Python for mathematicians...

SIAM WorkshopIntroduction to Python for mathematicians

and scientists

Mike Sussmansussmanm@math.pitt.edu

http://www.math.pitt.edu/%7esussmanm

October 18, 2014

1 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

2 / 56

Who am I?

I Part-time faculty in Math Dept.I Experience at Bettis labI Administer 2070/2071 Numerical Analysis labI Interested in numerical applications associated with fluid flowI Interested in large-scale scientific computing

3 / 56

Objectives

I Introduce Python programmingI Focus on use in scientific work

4 / 56

References

I Recent Python and NumPy/SciPy books from oreilly.comI Python Reference:https://docs.python.org/2/reference/index.html

I The Python Tutorialhttps://docs.python.org/2/tutorial

I 10-minute Python tutorialhttp://www.stavros.io/tutorials/python/

I Tentative NumPy Tutorialhttp://wiki.scipy.org/Tentative_NumPy_Tutorial

I Wonderful scientific Python blog by Greg von Winckelhttp://www.scientificpython.net/

5 / 56

Getting Python

1. Recommend using WinPython on MS-Windowshttp://sourceforge.net/p/winpython/wiki/Installation

2. Download version for Python 2.73. Run the installer4. Do not “register” it5. Navigate to Downloads\WinPython...

6. Run Spyder (not light)

6 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

7 / 56

What is Python?

I Computer programming languageI InterpretedI Object-orientedI Extended using “modules” and “packages”

8 / 56

Python and modules

I Core Python: bare-boneshttps://docs.python.org/2/reference/index.html

I “Standard Library”https://docs.python.org/2/library/index.html

I “Python package index” (50,000 packages)https://pypi.python.org

9 / 56

Python for scientific use

I numpyI scipyI matplotlib.pylabI sympyI SAGE

10 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

11 / 56

Running Python

I Use Spyder IDEI Run python in a Cygwin command window

12 / 56

File structure and line syntax

I No mandatory statement termination character.I Blocks are determined by indentationI Statements requiring a following block end with a colon (:)I Comments start with octothorpe (#), end at end of lineI Multiline comments are surrounded by triple double quotes (""")I Continue lines with \

13 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

14 / 56

Python basics

example1.py

1. Debugger2. x/3, -x/33. float(x)/34. conjugate(z), abs(w), w*w5. y0==y16. 2**100 (answer is long)

15 / 56

Basic data types

I Integers: 0, -5, 100I Floating-point numbers: 3.14159, 6.02e23I Complex numbers: 1.5 + 0.5jI Strings: "A string"

I Can use single quotesI Long (integers of arbitrary length)I Logical or Boolean: True, FalseI None

16 / 56

Basic operations

I +, -, *, /I ** (raise to power)I % (remainder)I and, or, notI >, <, >=, <=, ==, != (logical comparison)

17 / 56

Python array-type data types

I List: [0,"string",another list ]I Tuple: immutable list, surrounded by ()I Dictionary (dict): {"key1":"value1",2:3,"pi":3.14}

18 / 56

Getting help>>> help(complex)class complex(object)| complex(real[, imag]) -> complex number|| Create a complex number from a real part and an optional imaginary part.| This is equivalent to (real + imag*1j) where imag defaults to 0.|| Methods defined here:|| __abs__(...)| x.__abs__() <==> abs(x)|| __add__(...)| x.__add__(y) <==> x+y|| __div__(...)| x.__div__(y) <==> x/y|| conjugate(...)| complex.conjugate() -> complex|| Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j.| -----------------------------------------------| Data descriptors defined here:|| imag| the imaginary part of a complex number|| real| the real part of a complex number| 19 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

20 / 56

Functions, flow control, and import

example2.py

1. Debugger2. i/103. n, term, partialSum out of workspace after return!

21 / 56

Functions

I Functions begin with defI The def line ends with a colonI Function bodies are indentedI Functions use return to return values

22 / 56

Flow control

I if ... elif ... elseI forI whileI Bodies are indentedI range(N) generates 0, 1, ... , (N-1)

23 / 56

Importing and naming

I Include external libraries using importI import numpy

Imports all numpy functions, call as numpy.sin(x)I import numpy as np

Imports all numpy functions, call as np.sin(x)I from numpy import *

Imports all numpy functions, call as sin(x)I from numpy import sin

Imports only sin()

24 / 56

Pylab in Spyder

Automatically does following importsfrom pylab import *from numpy import *from scipy import *

You must do your own importing when writing code in files

I strongly suggest using names.import numpy as npimport scipy.linalg as laimport matplotlib.pyplot as plt

25 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

26 / 56

Subscripts

I x = [ ’a’, ’b’, ’c’, ’d’ ]

I x[0] is ’a’I x[3] is ’d’I x[0:2] is [ ’a’, ’b’ ]I x[-1] is ’d’

27 / 56

Subscripts

I x = [ ’a’, ’b’, ’c’, ’d’ ]I x[0] is ’a’

I x[3] is ’d’I x[0:2] is [ ’a’, ’b’ ]I x[-1] is ’d’

27 / 56

Subscripts

I x = [ ’a’, ’b’, ’c’, ’d’ ]I x[0] is ’a’I x[3] is ’d’

I x[0:2] is [ ’a’, ’b’ ]I x[-1] is ’d’

27 / 56

Subscripts

I x = [ ’a’, ’b’, ’c’, ’d’ ]I x[0] is ’a’I x[3] is ’d’I x[0:2] is [ ’a’, ’b’ ]

I x[-1] is ’d’

27 / 56

Subscripts

I x = [ ’a’, ’b’, ’c’, ’d’ ]I x[0] is ’a’I x[3] is ’d’I x[0:2] is [ ’a’, ’b’ ]I x[-1] is ’d’

27 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",d

y= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",d

y= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",d

y= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!

28 / 56

Equals, Copies, and Deep Copies>>> import copy as cp

>>> x=[1,2]>>> y=[3,4,x]>>> z=y>>> print "x=",x," y=",y," z=",zx= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

>>> c=cp.copy(y)>>> d=cp.deepcopy(y)>>> print "y=",y," z=",z," c=",c," d=",dy= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> y[0]="*">>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [1, 2]] z= ["*", 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

>>> z[2][0]=9>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

>>> c[2][1]=’c’>>> print "y=",y," z=",z," c=",c," d=",dy= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x[9, c]

Moral: Only deepcopy does it right!28 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

29 / 56

A Class is a generalized data type

I numpy defines a class called ndarrayI Define variable x of type ndarray, a one-dimensional array of

length 10:import numpy as npx=np.ndarray([10])

I Varibles of type ndarray are usually just called “array”.

30 / 56

Classes define members’ “attributes”

I Attributes can be dataI Usually, data attributes are “hidden”I Names start with double-underscoreI Programmers are trusted not to access such data

I Attributes can be functionsI Functions are provided to access “hidden” data

31 / 56

Examples of attributes

One way to generate a numpy array is:

import numpy as npx=np.array( [0, 0.1, 0.2, 0.4, 0.9, 3.14] )

I (data attribute) x.size is 6.I (data attribute) x.dtype is "float64" (quotes mean “string”)I (function attribute) x.item(2) is 0.2 (parentheses mean

“function”)I Copy function is provided by numpy:y = x.copy() ory = np.copy(x)

32 / 56

Operators can be overridden

I Multiplication and division are pre-defined (overridden)>>> 3*xarray([ 0. , 0.3 , 0.6 , 1.2 , 2.7 , 9.42])

I Brackets can be overridden to make things look “normal”>>> x[2] # bracket overridden0.2

33 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

34 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

35 / 56

Gauß integration

I Integrate Q =∫ 1

0 f (ξ)dξ

I Approximate it as Q ≈∑3

i=1 wi f (gi )

I wi and gi come from reference materials.

36 / 56

Example 3

example3.pyI Function of a vector returns a vectorI np.notI Extensive testing!I y=0.0*x+1.0⇐⇒ y=np.zeros_like(x)⇐⇒y=np.zeros( shape(x) )

I append() is a List attribute (function)

37 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

38 / 56

A boundary value problem by the finite elementmethod

−u′′ + u = f on [0,L]

u′(0) = 0 = u′(L)

1. Pick a basis of functions φi (x)

2. Write u(x) ≈∑

i uiφi (x)

3. Plug into equation4. Multiply equation through by φj (x) and integrate5. Solve system of equations for ui

39 / 56

FEM formulation

−u′′ + u = f (x) u′(0) = u′(L) = 0

Multiply through by a function v and integrate∫ L

0u′(x)v ′(x)dx +

[u′(x)v(x)

]L

0+

∫ L

0u(x)v(x)dx =

∫ L

0f (x)v(x)dx

The bracketed term drops out because of boundary values.Assume that an approximate solution can be written as

u(x) =N∑

j=1

ujφj (x)

Choosing v(x) = φi (x) yields

N∑j=1

(∫ L

0φ′i (x)φ′j (x)dx +

∫ L

0φi (x)φj (x)dx

)︸ ︷︷ ︸

aij

uj =

∫ L

0f (x)φi (x)dx︸ ︷︷ ︸

fi

.

AU = F.40 / 56

Do integrations elementwise

I Break [0,L] into N uniform subintervals ek : k = 0, . . . ,N − 1,each of width ∆x

I∫ L

0 φi (x)f (x) dx =∑

k

∫ekφi (x)f (x) dx

I∫

ekφi (x)f (x) dx =

∫ 10 φi (ξ)f (ξ)∆x dξ

I Inside ek , define

φ0(ξ) = 2.0(ξ − 0.5)(ξ − 1.0),

φ1(ξ) = 4.0ξ(1.0− ξ),

φ2(ξ) = 2.0ξ(ξ − 0.5)

41 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

42 / 56

What do the shape functions look like?

I Suppose ∆x = L/N so that ek = [k∆x , (k + 1)∆x ]

I Define xi = i∆x/2 for i = 0,1, . . . ,2NI x2N = LI ek = [x2k , x2K+2] for k = 0,1, . . . , (N − 1)

I Map ek → [0,1] is given by x = (k + ξ)∆xI Inside ek ,

ξ = (x − k∆x)/∆xφ0

k (x) = 2.0(ξ − 0.5)(ξ − 1.0),

φ1k (x) = 4.0ξ(1.0− ξ),

φ2k (x) = 2.0ξ(ξ − 0.5)

I Outside ek , φik = 0

43 / 56

Shape functions are a “partition of unity”

I Each φik is 1 at ξi ∈ ek and 0 elsewhere

I Each φ is piecewise quadraticI The unique piecewise quadratic function satisfying φi (xj ) = δij

agrees with one of the φik when xj ∈ ek .

I∑

i φi (x) = 1I φi form a basis of the space of piecewise quadratic functions with

breaks at xi .I u piecewise quadratic⇒ u(x) =

∑i uiφi (x)

I ui are called “degrees of freedom.”

44 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

45 / 56

Example 4

example4.pyI φ2

1 and φ02 together make φ4

I 2D subscripting: (Amat1[ m, n ])I plt.plot and plt.hold are like MatlabI np.linspace is like Matlab

46 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

47 / 56

Example 5

example5.pyI Solves −u′′ + u = f in weak form

∫u′v ′ +

∫uv =

∫fv with

Neumann boundary conditions on [0,5]

I Two tests: f0(x) = 1 and f1(x) = xI Two exact solutions: u0(x) = x and

u1(x) = cosh(5)−1sinh(5) cosh(x)− sinh(x) + x

48 / 56

Convergence results

Convergence resultsN error ratio5 0.00014244995355810 8.60661737944e-06 16.5512125470214320 5.21196552761e-07 16.5131893790300140 3.19766785929e-08 16.2992710842934480 1.97897364593e-09 16.1582134550725

160 1.23080146312e-10 16.0787397905218

Fourth-order

convergence is too high, a consequence of “superconvergence.”

49 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

50 / 56

Some differences with C++

I IndentationI **, and, orI longI (=) and copyingI Interpreted vs. compiledI No private variables

I Programmer must pretend not to see variables starting with __

I No constI Cannot have two functions with same name

I Allowed in C++ if signatures differentI Automatic garbage collectionI Variable types are implicitI Constructor syntaxI Extra parameter self

51 / 56

Some versions/variants of Python

I CPython: reference implementation of Python, written in CI Cython: superset of Python. Easy to write integrated C or C++

and Python codeI Jython: version of Python written in Java, can easily call Java

methods

52 / 56

TopicsIntroduction

Python, the language

Python language specificsPython basics, Example 1Functions, flow control, and import, Example 2Watch out, Alexander!Classes

A finite element programGauß integration, Example 3BVP by FEMShape functions, Example 4Code, Example 4FEM code, Example 5

Python language comments

FEniCS

53 / 56

FEniCS

FEniCS is a package for solving partial differential equationsexpressed in weak form.

1. You write a script in high-level PythonI Uses UFL form languageI Can use numpy, scipy, matplotlib.pyplot, etc.I Can use Viper for plotting

2. DOLFIN interprets the script3. UFL is passed to FFC for compilation4. Instant turns it into C++ callable from Python (“swig”)5. Linear algebra is passed to PETSc or UMFPACK

54 / 56

DOLFIN classes

I Sparse matrices and vectors via PETScI Solvers via PETSc can run in parallelI Eigenvalues via SLEPcI Newton solver for nonlinear equationsI Connected to ParaView for plotting solutions

55 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

Always start with this

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

I Mesh on [0,1]× [0,1]

I Uniform 6 cells in x0, 4 in x1

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

Linear Lagrange shape functions

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

I “Expression” causes acompilation

I x is a “global variable”

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

I on_boundary is a “global”variable

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

I Set Dirichlet b.c.I Can be more than one

boundaryI u0_boundary is used

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

I This is UFLI Specify weak formI −∆u = f ⇐⇒

∫∇u∇v dx =∫

f v dx

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

Define trial and test functionspaces

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

Define L(v) =∫

f (x)v(x) dx withf = −6

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

Define a(u, v) =∫∇u · ∇v dx

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

u is redefined as a Functioninstead of TrialFunction

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

Solve the systemL(v) = a(u, v) ∀v subject toboundary conditions.

56 / 56

FEniCS examplefrom dolfin import *

# Create mesh and define function spacemesh = UnitSquareMesh(6, 4)V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditionsu0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):return on_boundary

bc = DirichletBC(V, u0, u0_boundary)

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Constant(-6.0)a = inner(nabla_grad(u), nabla_grad(v))*dxL = f*v*dx

# Compute solutionu = Function(V)solve(a == L, u, bc)

# Plot solution and meshplot(u,interactive=True)plot(mesh,interactive=True)

I Plot u and mesh in twoframes.

I interactive=True causesthe plot to remain displayeduntil destroyed by mouse.

I Can also putinteractive() at the end.

56 / 56