Upload
others
View
15
Download
0
Embed Size (px)
Citation preview
SIAM WorkshopIntroduction to Python for mathematicians
and scientists
Mike [email protected]
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