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
end
Still 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.xml
Then: 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?