Skip to content

Commit 35f13de

Browse files
committed
Restructuring heat solver
1 parent 6c82634 commit 35f13de

File tree

4 files changed

+87
-63
lines changed

4 files changed

+87
-63
lines changed

numpy/heat-equation/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Note: Algorithm is stable only when
3737
Implement two dimensional heat equation with NumPy using the initial
3838
temperature field in the file [bottle.dat](bottle.dat) (the file consists of a
3939
header and 200 x 200 data array). As a boundary condition use fixed values as
40-
given in the initial field. You can start from the skeleton code in the file
41-
[skeleton.py](skeleton.py).
40+
given in the initial field. The main program that is provided in
41+
[heat_main.py](heat_main.py) can be used as such, implement the required
42+
functionality in the module [heat.py](heat.py) (look for **TODO**s).
4243

numpy/heat-equation/skeleton.py renamed to numpy/heat-equation/heat.py

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,6 @@
88
# Set the colormap
99
plt.rcParams['image.cmap'] = 'BrBG'
1010

11-
# Basic variables
12-
a = 0.5 # Diffusion constant.
13-
timesteps = 500 # Number of time-steps to evolve system.
14-
image_interval = 50 # write frequency for png files
15-
16-
# Grid spacings
17-
dx = 0.01
18-
dy = 0.01
19-
dx2 = dx**2
20-
dy2 = dy**2
21-
22-
# For stability, this is the largest interval possible
23-
# for the size of the time-step:
24-
dt = dx2*dy2 / ( 2*a*(dx2+dy2) )
25-
26-
# TODO: Read the initial temperature field from file
27-
2811

2912
def evolve(u, u_previous, a, dt):
3013
"""Explicit time evolution.
@@ -37,10 +20,20 @@ def evolve(u, u_previous, a, dt):
3720
# and the numerical Laplacian according the explicit time evolution method
3821

3922

40-
# Write figure of initial field to a file
41-
plt.imshow(field)
42-
plt.axis('off')
43-
plt.savefig('heat_{0:03d}.png'.format(0))
4423

24+
def iterate(field, field0, a, dx, dy, timesteps, image_interval):
25+
"""Run fixed number of time steps of heat equation"""
4526
# TODO: Implement the main iteration loop and write the figure
4627
# (to a new) file after each 'image_interval' iteration
28+
29+
def init_fields(filename):
30+
# TODO: Read the initial temperature field from file
31+
# Create also a copy of the field for the previous time step
32+
33+
return field, field0
34+
35+
def write_field(field, step):
36+
plt.gca().clear()
37+
plt.imshow(field)
38+
plt.axis('off')
39+
plt.savefig('heat_{0:03d}.png'.format(step))

numpy/heat-equation/heat_main.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from __future__ import print_function
2+
import time
3+
import argparse
4+
5+
from heat import init_fields, write_field, iterate
6+
7+
8+
def main(input_file='bottle.dat', a=0.5, dx=0.1, dy=0.1,
9+
timesteps=200, image_interval=4000):
10+
11+
# Initialise the temperature field
12+
field, field0 = init_fields(input_file)
13+
14+
print("Heat equation solver")
15+
print("Diffusion constant: {}".format(a))
16+
print("Input file: {}".format(input_file))
17+
print("Parameters")
18+
print("----------")
19+
print(" nx={} ny={} dx={} dy={}".format(field.shape[0], field.shape[1],
20+
dx, dy))
21+
print(" time steps={} image interval={}".format(timesteps,
22+
image_interval))
23+
24+
# Plot/save initial field
25+
write_field(field, 0)
26+
# Iterate
27+
t0 = time.time()
28+
iterate(field, field0, a, dx, dy, timesteps, image_interval)
29+
t1 = time.time()
30+
# Plot/save final field
31+
write_field(field, timesteps)
32+
33+
print("Simulation finished in {0} s".format(t1-t0))
34+
35+
if __name__ == '__main__':
36+
37+
# Process command line arguments
38+
parser = argparse.ArgumentParser(description='Heat equation')
39+
parser.add_argument('-dx', type=float, default=0.01,
40+
help='grid spacing in x-direction')
41+
parser.add_argument('-dy', type=float, default=0.01,
42+
help='grid spacing in y-direction')
43+
parser.add_argument('-a', type=float, default=0.5,
44+
help='diffusion constant')
45+
parser.add_argument('-n', type=int, default=200,
46+
help='number of time steps')
47+
parser.add_argument('-i', type=int, default=4000,
48+
help='image interval')
49+
parser.add_argument('-f', type=str, default='bottle.dat',
50+
help='input file')
51+
52+
args = parser.parse_args()
53+
54+
main(args.f, args.a, args.dx, args.dy, args.n, args.i)
55+
Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,11 @@
1-
from __future__ import print_function
21
import numpy as np
3-
import time
4-
52
import matplotlib
63
matplotlib.use('Agg')
74
import matplotlib.pyplot as plt
85

96
# Set the colormap
107
plt.rcParams['image.cmap'] = 'BrBG'
118

12-
# Basic parameters
13-
a = 0.5 # Diffusion constant
14-
timesteps = 200 # Number of time-steps to evolve system
15-
image_interval = 4000 # Write frequency for png files
16-
17-
# Grid spacings
18-
dx = 0.01
19-
dy = 0.01
20-
dx2 = dx**2
21-
dy2 = dy**2
22-
23-
# For stability, this is the largest interval possible
24-
# for the size of the time-step:
25-
dt = dx2*dy2 / ( 2*a*(dx2+dy2) )
26-
279
def evolve(u, u_previous, a, dt, dx2, dy2):
2810
"""Explicit time evolution.
2911
u: new temperature field
@@ -40,6 +22,21 @@ def evolve(u, u_previous, a, dt, dx2, dy2):
4022
u_previous[1:-1, :-2]) / dy2 )
4123
u_previous[:] = u[:]
4224

25+
def iterate(field, field0, a, dx, dy, timesteps, image_interval):
26+
"""Run fixed number of time steps of heat equation"""
27+
28+
dx2 = dx**2
29+
dy2 = dy**2
30+
31+
# For stability, this is the largest interval possible
32+
# for the size of the time-step:
33+
dt = dx2*dy2 / ( 2*a*(dx2+dy2) )
34+
35+
for m in range(1, timesteps+1):
36+
evolve(field, field0, a, dt, dx2, dy2)
37+
if m % image_interval == 0:
38+
write_field(field, m)
39+
4340
def init_fields(filename):
4441
# Read the initial temperature field from file
4542
field = np.loadtxt(filename)
@@ -52,26 +49,4 @@ def write_field(field, step):
5249
plt.axis('off')
5350
plt.savefig('heat_{0:03d}.png'.format(step))
5451

55-
def iterate(field, field0, timesteps, image_interval):
56-
for m in range(1, timesteps+1):
57-
evolve(field, field0, a, dt, dx2, dy2)
58-
if m % image_interval == 0:
59-
write_field(field, m)
60-
61-
62-
def main():
63-
# Initialise the temperature field
64-
field, field0 = init_fields('bottle.dat')
65-
# Plot/save initial field
66-
write_field(field, 0)
67-
# Iterate
68-
t0 = time.time()
69-
iterate(field, field0, timesteps, image_interval)
70-
t1 = time.time()
71-
# Plot/save final field
72-
write_field(field, timesteps)
73-
74-
print("Running time: {0}".format(t1-t0))
7552

76-
if __name__ == '__main__':
77-
main()

0 commit comments

Comments
 (0)