SIAM Workshop Introduction To Python For Mathematicians and Scientists

Download as pdf or txt
Download as pdf or txt
You are on page 1of 83

SIAM Workshop

Introduction to Python for mathematicians


and scientists

Mike Sussman
[email protected]
http://www.math.pitt.edu/%7esussmanm

October 18, 2014

1 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

2 / 56
Who am I?

I Part-time faculty in Math Dept.


I Experience at Bettis lab
I Administer 2070/2071 Numerical Analysis lab
I Interested in numerical applications associated with fluid flow
I Interested in large-scale scientific computing

3 / 56
Objectives

I Introduce Python programming


I Focus on use in scientific work

4 / 56
References

I Recent Python and NumPy/SciPy books from oreilly.com


I Python Reference:
https://docs.python.org/2/reference/index.html
I The Python Tutorial
https://docs.python.org/2/tutorial
I 10-minute Python tutorial
http://www.stavros.io/tutorials/python/
I Tentative NumPy Tutorial
http://wiki.scipy.org/Tentative_NumPy_Tutorial
I Wonderful scientific Python blog by Greg von Winckel
http://www.scientificpython.net/

5 / 56
Getting Python

1. Recommend using WinPython on MS-Windows


http://sourceforge.net/p/winpython/wiki/Installation
2. Download version for Python 2.7
3. Run the installer
4. Do not “register” it
5. Navigate to Downloads\WinPython...
6. Run Spyder (not light)

6 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

7 / 56
What is Python?

I Computer programming language


I Interpreted
I Object-oriented
I Extended using “modules” and “packages”

8 / 56
Python and modules

I Core Python: bare-bones


https://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 numpy
I scipy
I matplotlib.pylab
I sympy
I SAGE

10 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

11 / 56
Running Python

I Use Spyder IDE


I 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 indentation
I Statements requiring a following block end with a colon (:)
I Comments start with octothorpe (#), end at end of line
I Multiline comments are surrounded by triple double quotes (""")
I Continue lines with \

13 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

14 / 56
Python basics

example1.py

1. Debugger
2. x/3, -x/3
3. float(x)/3
4. conjugate(z), abs(w), w*w
5. y0==y1
6. 2**100 (answer is long)

15 / 56
Basic data types

I Integers: 0, -5, 100


I Floating-point numbers: 3.14159, 6.02e23
I Complex numbers: 1.5 + 0.5j
I Strings: "A string"
I Can use single quotes
I Long (integers of arbitrary length)
I Logical or Boolean: True, False
I None

16 / 56
Basic operations

I +, -, *, /
I ** (raise to power)
I % (remainder)
I and, or, not
I >, <, >=, <=, ==, != (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
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

20 / 56
Functions, flow control, and import

example2.py

1. Debugger
2. i/10
3. n, term, partialSum out of workspace after return!

21 / 56
Functions

I Functions begin with def


I The def line ends with a colon
I Function bodies are indented
I Functions use return to return values

22 / 56
Flow control

I if ... elif ... else


I for
I while
I Bodies are indented
I range(N) generates 0, 1, ... , (N-1)

23 / 56
Importing and naming

I Include external libraries using import


I 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 imports


from 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 np
import scipy.linalg as la
import matplotlib.pyplot as plt

25 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

26 / 56
Subscripts

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

27 / 56
Subscripts

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


I x[0] is ’a’

27 / 56
Subscripts

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


I x[0] is ’a’
I x[3] 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’ ]

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

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=",z
x= [1, 2] y= [3, 4, [1, 2]] z= [3, 4, [1, 2]]

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=",z
x= [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=",d
y= [3, 4, [1, 2]] z= [3, 4, [1, 2]] c= [3, 4, [1, 2]] d= [3, 4, [1, 2]]

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=",z
x= [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=",d
y= [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

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=",z
x= [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=",d
y= [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]]

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=",z
x= [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=",d
y= [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=",d

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=",z
x= [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=",d
y= [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=",d
y= ["*", 4, [9, 2]] z= ["*", 4, [9, 2]] c= [3, 4, [9, 2]] d= [3, 4, [1, 2]]

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=",z
x= [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=",d
y= [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=",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=",d

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=",z
x= [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=",d
y= [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=",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=",d
y= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x
[9, c]

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=",z
x= [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=",d
y= [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=",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=",d
y= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x
[9, c]

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=",z
x= [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=",d
y= [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=",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=",d
y= ["*", 4, [9, c]] z= ["*", 4, [9, c]] c= [3, 4, [9, c]] d= [3, 4, [1, 2]]

>>> x
[9, c]

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=",z
x= [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=",d
y= [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=",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=",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


Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

29 / 56
A Class is a generalized data type

I numpy defines a class called ndarray


I Define variable x of type ndarray, a one-dimensional array of
length 10:
import numpy as np
x=np.ndarray([10])
I Varibles of type ndarray are usually just called “array”.

30 / 56
Classes define members’ “attributes”

I Attributes can be data


I Usually, data attributes are “hidden”
I Names start with double-underscore
I Programmers are trusted not to access such data
I Attributes can be functions
I Functions are provided to access “hidden” data

31 / 56
Examples of attributes

One way to generate a numpy array is:

import numpy as np
x=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() or
y = np.copy(x)

32 / 56
Operators can be overridden

I Multiplication and division are pre-defined (overridden)


>>> 3*x
array([ 0. , 0.3 , 0.6 , 1.2 , 2.7 , 9.42])
I Brackets can be overridden to make things look “normal”
>>> x[2] # bracket overridden
0.2

33 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

34 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

35 / 56
Gauß integration

R1
I Integrate Q = 0
f (ξ)dξ
P3
I Approximate it as Q ≈ i=1 wi f (gi )
I wi and gi come from reference materials.

36 / 56
Example 3

example3.py
I Function of a vector returns a vector
I np.not
I 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
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

38 / 56
A boundary value problem by the finite element
method

−u 00 + u = f on [0, L]
0
u (0) = 0 = u 0 (L)

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


P
2. Write u(x) ≈ i ui φi (x)
3. Plug into equation
4. Multiply equation through by φj (x) and integrate
5. Solve system of equations for ui

39 / 56
FEM formulation
−u 00 + u = f (x) u 0 (0) = u 0 (L) = 0
Multiply through by a function v and integrate
Z L h iL Z L Z L
u 0 (x)v 0 (x)dx + u 0 (x)v (x) + u(x)v (x)dx = f (x)v (x)dx
0 0 0 0

The bracketed term drops out because of boundary values.


Assume that an approximate solution can be written as
N
X
u(x) = uj φj (x)
j=1

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


N
!
X Z L Z L Z L
φ0i (x)φ0j (x)dx + φi (x)φj (x)dx uj = f (x)φi (x)dx .
0 0
j=1
| {z } |0 {z }
aij 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
RL P R
I φ (x)f (x) dx = k ek φi (x)f (x) dx
0 i
R R1
I φ (x)f (x) dx = 0 φi (ξ)f (ξ)∆x dξ
ek i
I Inside ek , define

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


φ1 (ξ) = 4.0ξ(1.0 − ξ),
φ2 (ξ) = 2.0ξ(ξ − 0.5)

41 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM 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, . . . , 2N
I x2N = L
I ek = [x2k , x2K +2 ] for k = 0, 1, . . . , (N − 1)
I Map ek → [0, 1] is given by x = (k + ξ)∆x
I Inside ek ,

ξ = (x − k ∆x)/∆x
φ0k (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 quadratic
I The unique piecewise quadratic function satisfying φi (xj ) = δij
agrees with one of the φik when xj ∈ ek .
P
i φi (x) = 1
I

I φi form a basis of the space of piecewise quadratic functions with


breaks at xi .
P
I u piecewise quadratic ⇒ u(x) = i ui φi (x)
I ui are called “degrees of freedom.”

44 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

45 / 56
Example 4

example4.py
I φ21 and φ02 together make φ4
I 2D subscripting: (Amat1[ m, n ])
I plt.plot and plt.hold are like Matlab
I np.linspace is like Matlab

46 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

47 / 56
Example 5

example5.py
I Solves −u 00 + u = f in weak form
R 0 0 R R
u v + uv = fv with
Neumann boundary conditions on [0, 5]
I Two tests: f0 (x) = 1 and f1 (x) = x
I Two exact solutions: u0 (x) = x and
u1 (x) = cosh(5)−1
sinh(5) cosh(x) − sinh(x) + x

48 / 56
Convergence results

Convergence results
N error ratio
5 0.000142449953558
10 8.60661737944e-06 16.55121254702143
Fourth-order
20 5.21196552761e-07 16.51318937903001
40 3.19766785929e-08 16.29927108429344
80 1.97897364593e-09 16.1582134550725
160 1.23080146312e-10 16.0787397905218
convergence is too high, a consequence of “superconvergence.”

49 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

50 / 56
Some differences with C++
I Indentation
I **, and, or
I long
I (=) and copying
I Interpreted vs. compiled
I No private variables
I Programmer must pretend not to see variables starting with __
I No const
I Cannot have two functions with same name
I Allowed in C++ if signatures different
I Automatic garbage collection
I Variable types are implicit
I Constructor syntax
I Extra parameter self

51 / 56
Some versions/variants of Python

I CPython: reference implementation of Python, written in C


I Cython: superset of Python. Easy to write integrated C or C++
and Python code
I Jython: version of Python written in Java, can easily call Java
methods

52 / 56
Topics
Introduction
Python, the language
Python language specifics
Python basics, Example 1
Functions, flow control, and import, Example 2
Watch out, Alexander!
Classes
A finite element program
Gauß integration, Example 3
BVP by FEM
Shape functions, Example 4
Code, Example 4
FEM code, Example 5
Python language comments
FEniCS

53 / 56
FEniCS

FEniCS is a package for solving partial differential equations


expressed in weak form.
1. You write a script in high-level Python
I Uses UFL form language
I Can use numpy, scipy, matplotlib.pyplot, etc.
I Can use Viper for plotting
2. DOLFIN interprets the script
3. UFL is passed to FFC for compilation
4. 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 PETSc


I Solvers via PETSc can run in parallel
I Eigenvalues via SLEPc
I Newton solver for nonlinear equations
I Connected to ParaView for plotting solutions

55 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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)


Always start with this
# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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) I Mesh on [0, 1] × [0, 1]


# Define variational problem
u = TrialFunction(V)
I Uniform 6 cells in x0 , 4 in x1
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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)


Linear Lagrange shape functions
# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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) I “Expression” causes a


compilation
# Define variational problem
u = TrialFunction(V) I x is a “global variable”
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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)


I on_boundary is a “global”
# Define variational problem variable
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):


return on_boundary
I Set Dirichlet b.c.
bc = DirichletBC(V, u0, u0_boundary)
I Can be more than one
# Define variational problem boundary
u = TrialFunction(V)
v = TestFunction(V) I u0_boundary is used
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):


return on_boundary
I This is UFL
bc = DirichletBC(V, u0, u0_boundary)
I Specify weak form
# Define variational problem
R
u = TrialFunction(V)
I −∆u
R = f ⇐⇒ ∇u∇v dx =
v = TestFunction(V) f v dx
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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 trial and test function


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

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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)


R
Define L(v ) = f (x)v (x) dx with
# Define variational problem f = −6
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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) R


Define a(u, v ) = ∇u · ∇v dx
# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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)


u is redefined as a Function
# Define variational problem insteadof TrialFunction
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = 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) Solve the system


L(v ) = a(u, v ) ∀v subject to
# Define variational problem
u = TrialFunction(V) boundary conditions.
v = TestFunction(V)
f = Constant(-6.0)
a = inner(nabla_grad(u), nabla_grad(v))*dx
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56
FEniCS example
from dolfin import *

# Create mesh and define function space


mesh = UnitSquareMesh(6, 4)
V = FunctionSpace(mesh, ’Lagrange’, 1)

# Define boundary conditions


u0 = Expression(’1 + x[0]*x[0] + 2*x[1]*x[1]’)

def u0_boundary(x, on_boundary):


I Plot u and mesh in two
return on_boundary frames.
bc = DirichletBC(V, u0, u0_boundary) I interactive=True causes
# Define variational problem
the plot to remain displayed
u = TrialFunction(V) until destroyed by mouse.
v = TestFunction(V)
f = Constant(-6.0) I Can also put
a = inner(nabla_grad(u), nabla_grad(v))*dx interactive() at the end.
L = f*v*dx

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

# Plot solution and mesh


plot(u,interactive=True)
plot(mesh,interactive=True)
56 / 56

You might also like