Skip to content

Commit b7e4e1b

Browse files
committed
Restructuring heat solver
1 parent c9a6ebf commit b7e4e1b

File tree

5 files changed

+144
-129
lines changed

5 files changed

+144
-129
lines changed

interface/c/solution/heat-cffi.py

-66
This file was deleted.

interface/c/solution/heat-cython.py

-63
This file was deleted.

interface/c/solution/heat_cffi.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import numpy as np
2+
import matplotlib
3+
matplotlib.use('Agg')
4+
import matplotlib.pyplot as plt
5+
6+
from _evolve import ffi, lib
7+
8+
# Set the colormap
9+
plt.rcParams['image.cmap'] = 'BrBG'
10+
11+
def evolve(u, u_previous, a, dt, dx2, dy2):
12+
"""Explicit time evolution.
13+
u: new temperature field
14+
u_previous: previous field
15+
a: diffusion constant
16+
dt: time step. """
17+
18+
u_ptr = ffi.cast("double *", ffi.from_buffer(u))
19+
u_previous_ptr = ffi.cast("double *", ffi.from_buffer(u_previous))
20+
nx, ny = u.shape
21+
lib.evolve(u_ptr, u_previous_ptr, nx, ny, a, dt, dx2, dy2)
22+
23+
def iterate(field, field0, a, dx, dy, timesteps, image_interval):
24+
"""Run fixed number of time steps of heat equation"""
25+
26+
dx2 = dx**2
27+
dy2 = dy**2
28+
29+
# For stability, this is the largest interval possible
30+
# for the size of the time-step:
31+
dt = dx2*dy2 / ( 2*a*(dx2+dy2) )
32+
33+
for m in range(1, timesteps+1):
34+
evolve(field, field0, a, dt, dx2, dy2)
35+
if m % image_interval == 0:
36+
write_field(field, m)
37+
38+
def init_fields(filename):
39+
# Read the initial temperature field from file
40+
field = np.loadtxt(filename)
41+
field0 = field.copy() # Array for field of previous time step
42+
return field, field0
43+
44+
def write_field(field, step):
45+
plt.gca().clear()
46+
plt.imshow(field)
47+
plt.axis('off')
48+
plt.savefig('heat_{0:03d}.png'.format(step))
49+
50+

interface/c/solution/heat_cython.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import numpy as np
2+
import matplotlib
3+
matplotlib.use('Agg')
4+
import matplotlib.pyplot as plt
5+
6+
from evolve_cyt import evolve_py as evolve
7+
8+
# Set the colormap
9+
plt.rcParams['image.cmap'] = 'BrBG'
10+
11+
12+
def iterate(field, field0, a, dx, dy, timesteps, image_interval):
13+
"""Run fixed number of time steps of heat equation"""
14+
15+
dx2 = dx**2
16+
dy2 = dy**2
17+
18+
# For stability, this is the largest interval possible
19+
# for the size of the time-step:
20+
dt = dx2*dy2 / ( 2*a*(dx2+dy2) )
21+
22+
for m in range(1, timesteps+1):
23+
evolve(field, field0, a, dt, dx2, dy2)
24+
if m % image_interval == 0:
25+
write_field(field, m)
26+
27+
def init_fields(filename):
28+
# Read the initial temperature field from file
29+
field = np.loadtxt(filename)
30+
field0 = field.copy() # Array for field of previous time step
31+
return field, field0
32+
33+
def write_field(field, step):
34+
plt.gca().clear()
35+
plt.imshow(field)
36+
plt.axis('off')
37+
plt.savefig('heat_{0:03d}.png'.format(step))
38+
39+

interface/c/solution/heat_main.py

+55
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_cffi 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+

0 commit comments

Comments
 (0)