Python is (line many script languages) very intuitive.
print('Hello world!') a = 42 # integer b = 42 / 21 + 10 # = 12 my_list = [1, 3, 'Hello World!'] # list: all types permitted! print(my_list[0]) # 0-based indexing for i in range(4): # i in 0,...,3 print(i) for elem in my_list: print(elem) d = { 'Hallo': 'hello', # dictionary ("map") 'Welt': 'world', 42: 'fourty-two'} print(d['Hallo']) # -> hello tuple = (4,3,1) if tuple == (4,): # easy to compare! print('yeah')
# mymodule.py def square(a): # functions can be defined anywhere return a*a # with arbitrary names (like variables) def arnoldi(A, v, maxiter=10, ortho='mgs'): # default arguments # compute V, H return V, H # multiple return arguments
import mymodule # import is possible anywhere in the code print( mymodule.square(3) )
from mymodule import square, arnoldi print( square(3) ) V, H = arnoldi(A, v, ortho='house') # maxiter is set to default (10)
NumPy is the basis package for numerics (based on BLAS, LAPACK, etc.).
from numpy import array, ones, dot # N-dim Arrays v = array([1,2,3]) # 1-dim arr, shape==(3,) v = ones(5) # 1-dim arr, shape==(5,) v = ones((5,1)) # 2-dim arr, shape==(5,1) A = array([[1,2,3],[4,5,6]]) # 2x3-matrix: 2-dim arr, shape==(2,3) A = ones((5,5)) # 5x5-matrix: 2-dim arr, shape==(5,5) b = dot(A, v) # A*v
The default data type in NumPy are NumPy arrays; there are also NumPy matrices. The main difference is that one can use the *-operator for matrix-matrix multiplication (as in MATLAB). Many (especially the NumPy community) recommend NumPy arrays.
Well-known commands in NumPy:
MATLAB's \-operator: solve(A,b).
For more info, see NumPy documentation.
Interesting for us:
For more info, see SciPy documentation.
from matplotlib import pyplot as pp data = [x**2 for x in range(100)] # list comprehension! pp.plot(data) pp.show()
LaTeX-integration via matplotlib2tikz.
import sympy as smp x, y = smp.symbols('x, y') f = x**2 + sin(x) * y diff(f, x) diff(f, x, 2)full-featured computer algebra system
Always stay as high-level as possible.
J = [ X(NODES(2),1)-X(NODES(1),1) , X(NODES(3),1)-X(NODES(1),1) ; X(NODES(2),2)-X(NODES(1),2) , X(NODES(3),2)-X(NODES(1),2) ]; AbsDetJ = abs( J(1,1)*J(2,2) - J(1,2)*J(2,1) ) ; L = (eps/(2*AbsDetJ)) * [ J(1,2)^2 + J(2,2)^2 , - J(1,1)*J(1,2) - J(2,1)*J(2,2) ; 0 , J(1,1)^2 + J(2,1)^2 ]; A = z3A(1,1) = L(1,1) + 2*L(1,2) + L(2,2) + AbsDetJ/12 ; A(1,2) = - L(1,1) - L(1,2) + AbsDetJ/24 ; A(1,3) = - L(1,2) - L(2,2) + AbsDetJ/24 ; A(2,1) = - L(1,1) - L(1,2) + AbsDetJ/24 ; A(2,2) = L(1,1) + AbsDetJ/12 ; A(2,3) = L(1,2) + AbsDetJ/24 ; A(3,1) = - L(1,2) - L(2,2) + AbsDetJ/24 ; A(3,2) = L(1,2) + AbsDetJ/12 ; A(3,3) = L(2,2) + AbsDetJ/12 ;
for r=1:size(ECT,1) localStiffnessMatrix = local_assemble(ECT(r,:),X,eps); for alpha=1:3 i = ECT(r,alpha); for beta= 1:3 j = ECT(r,beta); K(i,j) = K(i,j) + localStiffnessMatrix(alpha,beta); end end endStill missing:
from dolfin import * # Create mesh and define function space mesh = UnitSquareMesh(20, 20) 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 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) plot(mesh) # Dump solution to file in VTK format file = File('poisson.pvd') file << u # Hold plot interactive()
prm = parameters['krylov_solver'] # short form prm['absolute_tolerance'] = 0.0 prm['relative_tolerance'] = 1E-13 prm['maximum_iterations'] = 10000 prm['monitor_convergence'] = True solve(a == L, u, [bc0, bc1], solver_parameters={'linear_solver': 'cg', 'preconditioner': 'ilu'} )
from dolfin import * parameters['linear_algebra_backend'] = 'uBLAS' [...] a = inner(nabla_grad(u), nabla_grad(v))*dx L = f*v*dx + g*v*ds A = assemble(a, bcs=[bc0,bc1]) b = assemble(L, bcs=[bc0,bc1])Output:
$ python ex5.py (array([ 0, 3, 8, ..., 11433, 11438, 11441]), array([ 0, 1, 2, ..., 1678, 1679, 1680]), array([ 1. , -0.5, -0.5, ..., 0. , 0. , 1. ])) [ 0.00114583 0.0065625 0. ..., 0. 1. 1. ]
UnitSquare(4, 4) UnitCube(4, 4, 4) Rectangle(a, 0, b, 1, nr, nt, 'crossed') [...]
$ dolfin-convert mymesh.msh mymesh.xml dolfin-convert mymesh.msh mymesh.xml Converting from Gmsh format (.msh, .gmsh) to DOLFIN XML format Expecting 2001 vertices Found all vertices Expecting 10469 cells Found all cells Conversion done $ ls mymesh*.xml mymesh_physical_region.xml mymesh.xmlThen: Run Dolfin with those XML meshes.
a = u*v*dx + dt*inner(grad(u), grad(v))*dx L = y_1*v*dx + dt*f*v*dx while t < T: solve(a == L, y) t += dt y_1.assign(y)
Questions?