FDM solvers in Python – a framework Europython, 7-9 June 2004 Åsmund Ødegård

advertisement
FDM solvers in Python – a framework
Europython,
7-9 June 2004
Åsmund Ødegård
Simula Research Laboratory
About me
Motivation
Building blocks
Putting it together
About me
Name: Åsmund Ødegård
Position: Ph.D student, IT-manager at Simula
Research Laboratory AS, Norway.
Research interests
Object Oriented numerics, focus on PDEs
Parallel computing
Linux clusters
Motivation - math
ut (x, t) = ∇2 u(x, t)
Motivation - math
ut (x, t) = ∇2 u(x, t)
Example, simple model of heat transfer
Motivation - math
ut (x, t) = ∇2 u(x, t)
Apply FDM
Example, simple model of heat transfer
−uki
uk+1
i
∆t
=
uki−1 −2uki +uki+1
∆x2
Motivation - math
ut (x, t) = ∇2 u(x, t)
Apply FDM
Example, simple model of heat transfer
−uki
uk+1
i
∆t
k +
=
u
uk+1
i
i
=
uki−1 −2uki +uki+1
∆x2
∆t
k
(u
i−1
∆x2
− 2uki + uki+1 )
Motivation - math
ut (x, t) = ∇2 u(x, t)
Apply FDM
Example, simple model of heat transfer
−uki
uk+1
i
∆t
k +
=
u
uk+1
i
i
=
uki−1 −2uki +uki+1
∆x2
∆t
k
(u
i−1
∆x2
− 2uki + uki+1 )
Add boundary and initial conditions
Motivation
Motivation
Related work:
- Cogito, K. Åhlander et.al
- A++/P++, Dan. Quinlan et.al
- And many others contributions
Priorities
1. Abstractions
2. Parallelization
3. Efficiency
Motivation
Related work:
- Cogito, K. Åhlander et.al
- A++/P++, Dan. Quinlan et.al
- And many others contributions
Priorities
1. Abstractions
2. Parallelization
3. Efficiency
Part of the SciTools project
Building blocks
Grid
Basic abstraction
Number of dimensions
Domain and partition
Methods:
– setSize
– innerPoints
– boundary
– corners
Building blocks
Grid
Stencil
Main abstraction
Define action of the PDE in
one point.
Same stencil in many points,
e.g all inner-points and all
boundary points.
Stencils may (easily) be defined
dimension–independent.
k +
uk+1
=
u
i
i
∆t
k
(u
2
i−1
∆x
1
− 2uki + uki+1 )
1
-4
1
1
Building blocks
Grid
from Stencil import Stencil
s = Stencil(1,1) # 1D, variable coefficients
Stencil
s.addNode((-1),[lambda x: 0.5*x*x])
s.addNode((1),[lambda x: 0.5*x*x])
s.addNode((0),[lambda x: 2])
1
This is the simple usage – It may
also be convenient to subclass
Stencil.
1
-4
1
1
Building blocks
Grid
Stencil
bi = map(lambda x: 0,range(self.nsd))
dx = grid.division
for i in xrange(self.nsd):
# copy the basic index into changeable object
cbi = copy(bi)
# add "left" node
cbi[i]=-1
ti=tuple(cbi)
value = 1.0/(dx[i]*dx[i])
1
self.addNode(ti,value)
# add "right" node
cbi[i]=1
1
-4
ti=tuple(cbi)
self.addNode(ti,value)
# add "center"
1
cbi[i]=0
ti=tuple(cbi)
value=-2.0/(dx[i]*dx[i])
self.addNode(ti,value)
1
Building blocks
Grid
Stencil
StencilList
StencilList – Main abstraction
Build the action of the PDE
as a list of stencils.
Hold two lists:
– List of Stencils
– List of iterators!
Iterators define points where
each Stencil will be applied.
1
1
-4
1
1
-4
2
1
1
Building blocks
Grid
Field – Basic abstraction
Data, a Numeric array
Pointer to a Grid object
Stencil
Methods:
– get and set item
StencilList
– fill, taking some function as argument
– plot, ...
Field
Building blocks
Grid
1
-4
1
2
Stencil
1
1
StencilList
-4
1
1
1
Field
One explicit step: un+1 = stencillist(un )
Building blocks
An important issue: How to traverse the grid?
Building blocks
An important issue: How to traverse the grid?
Our solution: Use iterators!
- Benefit: We don’t need to create list for all
indices in memory.
- Drawback: speed
- Simplest case: (1,1,...) - (n-1,m-1,...), which
represent all inner nodes in the grid.
Can also be done with list-comprehension (but
that will produce the list in memory)
– <code>: simpletuple.py
Building blocks
What if you want a Neumann–condition on part of
the boundary?
1
-4
2
1
Building blocks
What if you want a Neumann–condition on part of
the boundary?
1
-4
1
2
We have implemented a generator
which provide an iterator for each
part of the boundary, with necessary auxiliary information.
– <code>: advancedtuple.py
An example
Consider a simple Heat equation:
u t = ∇2 u
u(x, 0) = f (x),
ux (x, t) = g(x, t),
x∈Ω
x∈Ω
x ∈ ∂Ω
Assume further that we want to solve this on the unit
square with f and g given as initialfunc and neumanncond, respectively.
An example (run it!)
g = Grid(([0.0,1.0],[0.0,1.0]),(100,100))
u = Field(g)
t = 0; ∆t = T/n;
sl = StencilList(g)
innerstencil = Identity(g) + ∆t*Laplace(g)
innerind = sl.addStencil(innerstencil,g.innerPoints())
sl += NeumannBoundary.create(sl[innerind],g,neumanncond)
u.fill(initialfunc)
for t < T:
u = sl(u)
t += ∆t
Conclusions
We have created a framework suitable for
experimenting with FDM.
The syntax is compact.
It can be used both interactively in a “matlab” kind
of style, or you can create solver classes utilizing
the presented abstractions.
Some Future steps
Today, the framework only support explicit
methods – implicit methods must also be
addressed. We need to couple with a linear
algebra library.
Automatic parallelization. The stencils provide
the communication pattern.
More geometry!
More focus on performance, e.g. vectorization of
operators, implementing c or fortran modules for
certain operations.
Download