Skip to content

Commit 6f7dffe

Browse files
committed
examples: Add a simple 2D superstep example
1 parent 9bec07b commit 6f7dffe

1 file changed

Lines changed: 114 additions & 0 deletions

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
''' Script that demonstrates the functionality of the superstep in 2D
2+
"Ripple on a pond"
3+
'''
4+
import matplotlib.pyplot as plt
5+
import numpy as np
6+
from devito import ConditionalDimension, Eq, Function, Grid, Operator, TimeFunction, solve
7+
from devito.timestepping.superstep import superstep_generator
8+
9+
10+
def gaussian2d(xx, yy, mu=0, sigma_sq=1):
11+
return np.exp(-((xx - mu)**2 + (yy - mu)**2)/(2*sigma_sq))/(np.sqrt(2*np.pi*sigma_sq))
12+
13+
# Spatial Domain
14+
shape = (101, 101)
15+
origin = (0., 0.)
16+
extent = (1000, 1000) # 1kmx1km
17+
# Time Domain
18+
t0 = 0
19+
t1 = 0.5
20+
critical_dt = 0.0047140
21+
# Initial Condition
22+
mu = 500
23+
sigma_sq = 5000
24+
zlim = 1/(2*np.sqrt(2*np.pi*sigma_sq))
25+
26+
27+
def ripple_on_pond(step=1, snapshots=1):
28+
# Construct 2D Grid
29+
grid = Grid(shape=shape, extent=extent)
30+
x, y = grid.dimensions
31+
32+
# Need to ensure that the velocity function supports the largest superstep stencil
33+
velocity = Function(name="velocity", grid=grid, space_order=(2, step, step))
34+
velocity.data[:] = 1500
35+
36+
u = TimeFunction(name="u", grid=grid, time_order=2, space_order=2)
37+
38+
# The source/sink terms are injected in after the fact (???)
39+
pde = (1/velocity**2)*u.dt2 - u.laplace # + damp*u.dt
40+
stencil = Eq(u.forward, solve(pde, u.forward))
41+
42+
# Initial condition
43+
x = np.linspace(origin[0], extent[0], shape[0])
44+
y = np.linspace(origin[1], extent[1], shape[1])
45+
xx, yy = np.meshgrid(x, y)
46+
ic = gaussian2d(xx, yy, mu=mu, sigma_sq=sigma_sq)
47+
48+
# Stencil and operator
49+
if step == 1:
50+
# Non-superstep case
51+
new_u = u
52+
stencil = [stencil]
53+
new_u.data[0, :] = ic
54+
new_u.data[1, :] = ic
55+
new_u.data[2, :] = ic
56+
else:
57+
new_u, new_u_p, *stencil = superstep_generator(u, stencil.rhs, step)
58+
59+
new_u.data[0, :] = ic
60+
new_u.data[1, :] = ic
61+
new_u_p.data[0, :] = ic
62+
new_u_p.data[1, :] = ic
63+
64+
tn = int(np.ceil((t1 - t0)/critical_dt))
65+
dt = t1/tn
66+
67+
# Snapshot the solution
68+
factor = int(np.ceil(tn/(snapshots + 1)))
69+
t_sub = ConditionalDimension('t_sub', parent=grid.time_dim, factor=factor)
70+
u_save = TimeFunction(
71+
name='usave', grid=grid,
72+
time_order=0, space_order=2,
73+
save=snapshots//step + 1, time_dim=t_sub
74+
)
75+
save = Eq(u_save, new_u)
76+
77+
op = Operator([*stencil, save], opt='noop')
78+
op(dt=dt)
79+
80+
if step == 1:
81+
u_save.data[0, :] = ic
82+
83+
return u_save.data
84+
85+
if __name__ == '__main__':
86+
# Supersteps
87+
k = [1, 3, 4]
88+
# Snapshots
89+
m = 13
90+
fig, axes = plt.subplots(len(k), m)
91+
for step, ax_row in zip(k, axes, strict=True):
92+
data = ripple_on_pond(step=step, snapshots=m)
93+
idx = 0
94+
for ii, ax in enumerate(ax_row):
95+
if ii % step == 0:
96+
ax.imshow(
97+
data[idx, :, :].T,
98+
extent=[origin[0], extent[0], extent[1], origin[1]],
99+
vmin=-zlim, vmax=zlim,
100+
cmap='seismic'
101+
)
102+
idx += 1
103+
else:
104+
ax.remove()
105+
fig.subplots_adjust(
106+
left=0.05,
107+
bottom=0.025,
108+
right=0.99,
109+
top=0.97,
110+
wspace=0.06,
111+
hspace=0.06
112+
)
113+
plt.show()
114+

0 commit comments

Comments
 (0)