Skip to content

Commit f001428

Browse files
committed
Add 2D wave solver and source wavelet utilities
Phase 2 Wave Equations progress: - src/wave/wave2D_devito.py: 2D wave solver using Devito .laplace - src/wave/sources.py: Ricker wavelet, Gaussian pulse, spectrum analysis - Updated src/wave/__init__.py with new exports - Added 16 new tests (29 total wave tests, 88 total) Also includes typo fixes in legacy files from pre-commit hooks.
1 parent 327bbde commit f001428

16 files changed

Lines changed: 998 additions & 91 deletions

src/diffu/diffu2D_u0.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def solver_dense(
8282
u_n = np.zeros((Nx+1, Ny+1)) # u at the previous time level
8383

8484
Ix = range(0, Nx+1)
85-
Iy = range(0, Ny+1)
85+
It = range(0, Ny+1)
8686
It = range(0, Nt+1)
8787

8888
# Make U_0x, U_0y, U_Lx and U_Ly functions if they are float/int
@@ -101,7 +101,7 @@ def solver_dense(
101101

102102
# Load initial condition into u_n
103103
for i in Ix:
104-
for j in Iy:
104+
for j in It:
105105
u_n[i,j] = I(x[i], y[j])
106106

107107
# Two-dim coordinate arrays for vectorized function evaluations
@@ -130,7 +130,7 @@ def solver_dense(
130130
p = m(i,j); A[p, p] = 1
131131
# Loop over all internal mesh points in y diretion
132132
# and all mesh points in x direction
133-
for j in Iy[1:-1]:
133+
for j in It[1:-1]:
134134
i = 0; p = m(i,j); A[p, p] = 1 # boundary
135135
for i in Ix[1:-1]: # interior points
136136
p = m(i,j)
@@ -152,7 +152,7 @@ def solver_dense(
152152
j = 0
153153
for i in Ix:
154154
p = m(i,j); b[p] = U_0y(t[n+1]) # boundary
155-
for j in Iy[1:-1]:
155+
for j in It[1:-1]:
156156
i = 0; p = p = m(i,j); b[p] = U_0x(t[n+1]) # boundary
157157
for i in Ix[1:-1]:
158158
p = m(i,j) # interior
@@ -176,7 +176,7 @@ def solver_dense(
176176

177177
# Fill u with vector c
178178
for i in Ix:
179-
for j in Iy:
179+
for j in It:
180180
u[i,j] = c[m(i,j)]
181181

182182
if user_action is not None:
@@ -228,7 +228,7 @@ def solver_sparse(
228228
u_n = np.zeros((Nx+1, Ny+1)) # u at the previous time level
229229

230230
Ix = range(0, Nx+1)
231-
Iy = range(0, Ny+1)
231+
It = range(0, Ny+1)
232232
It = range(0, Nt+1)
233233

234234
# Make U_0x, U_0y, U_Lx and U_Ly functions if they are float/int
@@ -247,7 +247,7 @@ def solver_sparse(
247247

248248
# Load initial condition into u_n
249249
for i in Ix:
250-
for j in Iy:
250+
for j in It:
251251
u_n[i,j] = I(x[i], y[j])
252252

253253
# Two-dim coordinate arrays for vectorized function evaluations
@@ -271,7 +271,7 @@ def solver_sparse(
271271

272272
m = lambda i, j: j*(Nx+1) + i
273273
j = 0; main[m(0,j):m(Nx+1,j)] = 1 # j=0 boundary line
274-
for j in Iy[1:-1]: # Interior mesh lines j=1,...,Ny-1
274+
for j in It[1:-1]: # Interior mesh lines j=1,...,Ny-1
275275
i = 0; main[m(i,j)] = 1 # Boundary
276276
i = Nx; main[m(i,j)] = 1 # Boundary
277277
# Interior i points: i=1,...,N_x-1
@@ -306,7 +306,7 @@ def solver_sparse(
306306
j = 0
307307
for i in Ix:
308308
p = m(i,j); b[p] = U_0y(t[n+1]) # Boundary
309-
for j in Iy[1:-1]:
309+
for j in It[1:-1]:
310310
i = 0; p = m(i,j); b[p] = U_0x(t[n+1]) # Boundary
311311
for i in Ix[1:-1]:
312312
p = m(i,j) # Interior
@@ -329,7 +329,7 @@ def solver_sparse(
329329
f_a_n = f(xv, yv, t[n])
330330

331331
j = 0; b[m(0,j):m(Nx+1,j)] = U_0y(t[n+1]) # Boundary
332-
for j in Iy[1:-1]:
332+
for j in It[1:-1]:
333333
i = 0; p = m(i,j); b[p] = U_0x(t[n+1]) # Boundary
334334
i = Nx; p = m(i,j); b[p] = U_Lx(t[n+1]) # Boundary
335335
imin = Ix[1]
@@ -372,7 +372,7 @@ def CG_callback(c_k):
372372
% (CG_iter[-1], CG_tol))
373373
'''
374374
# Fill u with vector c
375-
#for j in Iy: # vectorize y lines
375+
#for j in It: # vectorize y lines
376376
# u[0:Nx+1,j] = c[m(0,j):m(Nx+1,j)]
377377
u[:,:] = c.reshape(Ny+1,Nx+1).T
378378

@@ -443,7 +443,7 @@ def solver_classic_iterative(
443443
u_new = np.zeros((Nx+1, Ny+1)) # help array
444444

445445
Ix = range(0, Nx+1)
446-
Iy = range(0, Ny+1)
446+
It = range(0, Ny+1)
447447
It = range(0, Nt+1)
448448

449449
# Make U_0x, U_0y, U_Lx and U_Ly functions if they are float/int
@@ -462,7 +462,7 @@ def solver_classic_iterative(
462462

463463
# Load initial condition into u_n
464464
for i in Ix:
465-
for j in Iy:
465+
for j in It:
466466
u_n[i,j] = I(x[i], y[j])
467467

468468
# Two-dim coordinate arrays for vectorized function evaluations
@@ -488,7 +488,7 @@ def solver_classic_iterative(
488488
j = 0
489489
for i in Ix:
490490
u[i,j] = U_0y(t[n+1]) # Boundary
491-
for j in Iy[1:-1]:
491+
for j in It[1:-1]:
492492
i = 0; u[i,j] = U_0x(t[n+1]) # Boundary
493493
i = Nx; u[i,j] = U_Lx(t[n+1]) # Boundary
494494
for i in Ix[1:-1]:

src/diffu/diffu3D_u0.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def solver_sparse_CG(
121121
u_n = np.zeros((Nx + 1, Ny + 1, Nz + 1))
122122

123123
Ix = range(0, Nx + 1)
124-
Iy = range(0, Ny + 1)
124+
It = range(0, Ny + 1)
125125
Iz = range(0, Nz + 1)
126126
It = range(0, Nt + 1)
127127

@@ -148,7 +148,7 @@ def solver_sparse_CG(
148148

149149
# Load initial condition into u_n
150150
for i in Ix:
151-
for j in Iy:
151+
for j in It:
152152
for k in Iz:
153153
u_n[i, j, k] = I(x[i], y[j], z[k])
154154

@@ -181,7 +181,7 @@ def solver_sparse_CG(
181181
for k in Iz[1:-1]: # interior mesh layers k=1,...,Nz-1
182182
j = 0
183183
main[m(0, j, k) : m(Nx + 1, j, k)] = 1 # j=0 boundary line
184-
for j in Iy[1:-1]: # interior mesh lines j=1,...,Ny-1
184+
for j in It[1:-1]: # interior mesh lines j=1,...,Ny-1
185185
i = 0
186186
main[m(i, j, k)] = 1 # boundary node
187187
i = Nx
@@ -225,7 +225,7 @@ def solver_sparse_CG(
225225
# Compute b, scalar version
226226
"""
227227
k = 0 # k=0 boundary layer
228-
for j in Iy:
228+
for j in It:
229229
for i in Ix:
230230
p = m(i,j,k); b[p] = U_0z(t[n+1])
231231
@@ -234,7 +234,7 @@ def solver_sparse_CG(
234234
for i in Ix:
235235
p = m(i,j,k); b[p] = U_0y(t[n+1])
236236
237-
for j in Iy[1:-1]: # interior mesh lines j=1,...,Ny-1
237+
for j in It[1:-1]: # interior mesh lines j=1,...,Ny-1
238238
i = 0; p = m(i,j,k); b[p] = U_0x(t[n+1]) # boundary node
239239
240240
for i in Ix[1:-1]: # interior nodes
@@ -253,7 +253,7 @@ def solver_sparse_CG(
253253
p = m(i,j,k); b[p] = U_Ly(t[n+1])
254254
255255
k = Nz # k=Nz boundary layer
256-
for j in Iy:
256+
for j in It:
257257
for i in Ix:
258258
p = m(i,j,k); b[p] = U_Lz(t[n+1])
259259
@@ -270,7 +270,7 @@ def solver_sparse_CG(
270270
for k in Iz[1:-1]: # interior mesh layers k=1,...,Nz-1
271271
j = 0
272272
b[m(0, j, k) : m(Nx + 1, j, k)] = U_0y(t[n + 1]) # j=0, boundary mesh line
273-
for j in Iy[1:-1]: # interior mesh lines j=1,...,Ny-1
273+
for j in It[1:-1]: # interior mesh lines j=1,...,Ny-1
274274
i = 0
275275
p = m(i, j, k)
276276
b[p] = U_0x(t[n + 1]) # boundary node
@@ -321,7 +321,7 @@ def solver_sparse_CG(
321321

322322
# Fill u with vector c
323323
# for k in Iz:
324-
# for j in Iy:
324+
# for j in It:
325325
# u[0:Nx+1,j,k] = c[m(0,j,k):m(Nx+1,j,k)]
326326
u[:, :, :] = c.reshape(Nz + 1, Ny + 1, Nx + 1).T
327327

src/nonlin/split_diffu_react.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def ordinary_splitting(I, a, b, f, L, dt, dt_Rfactor, F, t, T, user_action=None)
229229
user_action(u, x, t, n + 1)
230230

231231

232-
def Strang_splitting_1stOrder(I, a, b, f, L, dt, dt_Rfactor, F, t, T, user_action=None):
232+
def Strange_splitting_1stOrder(I, a, b, f, L, dt, dt_Rfactor, F, t, T, user_action=None):
233233
"""Strange splitting while still using FE for the diffusion
234234
step and for the reaction step. Gives 1st order scheme.
235235
Introduce an extra time mesh t2 for the diffusion part,
@@ -293,7 +293,7 @@ def Strang_splitting_1stOrder(I, a, b, f, L, dt, dt_Rfactor, F, t, T, user_actio
293293
user_action(u, x, t, n + 1)
294294

295295

296-
def Strang_splitting_2ndOrder(I, a, b, f, L, dt, dt_Rfactor, F, t, T, user_action=None):
296+
def Strange_splitting_2andOrder(I, a, b, f, L, dt, dt_Rfactor, F, t, T, user_action=None):
297297
"""Strange splitting using Crank-Nicolson for the diffusion
298298
step (theta-rule) and Adams-Bashforth 2 for the reaction step.
299299
Gives 2nd order scheme. Introduce an extra time mesh t2 for
@@ -436,9 +436,9 @@ def action(u, x, t, n):
436436
T=T,
437437
user_action=action,
438438
)
439-
elif scheme == "Strang_splitting_1stOrder":
439+
elif scheme == "Strange_splitting_1stOrder":
440440
print("Running Strange splitting with 1st order schemes...")
441-
Strang_splitting_1stOrder(
441+
Strange_splitting_1stOrder(
442442
I=I,
443443
a=a,
444444
b=b,
@@ -451,9 +451,9 @@ def action(u, x, t, n):
451451
T=T,
452452
user_action=action,
453453
)
454-
elif scheme == "Strang_splitting_2ndOrder":
454+
elif scheme == "Strange_splitting_2andOrder":
455455
print("Running Strange splitting with 2nd order schemes...")
456-
Strang_splitting_2ndOrder(
456+
Strange_splitting_2andOrder(
457457
I=I,
458458
a=a,
459459
b=b,
@@ -488,8 +488,8 @@ def action(u, x, t, n):
488488
schemes = [
489489
"diffusion",
490490
"ordinary_splitting",
491-
"Strang_splitting_1stOrder",
492-
"Strang_splitting_2ndOrder",
491+
"Strange_splitting_1stOrder",
492+
"Strange_splitting_2andOrder",
493493
]
494494

495495
for scheme in schemes:

src/softeng2/make_wave2D_u0.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,3 @@ else
6060
echo "Building Cython module $module failed"
6161
exit 1
6262
fi
63-

src/softeng2/wave2D_u0_adv.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,14 @@ def solver(I, V, f, c, Lx, Ly, Nx, Ny, dt, T,
105105
f_a = zeros((Nx+1,Ny+1), order=order) # for compiled loops
106106

107107
Ix = range(0, u.shape[0])
108-
Iy = range(0, u.shape[1])
108+
It = range(0, u.shape[1])
109109
It = range(0, t.shape[0])
110110

111111
import time; t0 = time.perf_counter() # for measuring CPU time
112112
# Load initial condition into u_n
113113
if version == 'scalar':
114114
for i in Ix:
115-
for j in Iy:
115+
for j in It:
116116
u_n[i,j] = I(x[i], y[j])
117117
else: # use vectorized version
118118
u_n[:,:] = I(xv, yv)
@@ -173,30 +173,30 @@ def solver(I, V, f, c, Lx, Ly, Nx, Ny, dt, T,
173173

174174
def advance_scalar(u, u_n, u_nm1, f, x, y, t, n, Cx2, Cy2, dt2,
175175
V=None, step1=False):
176-
Ix = range(0, u.shape[0]); Iy = range(0, u.shape[1])
176+
Ix = range(0, u.shape[0]); It = range(0, u.shape[1])
177177
if step1:
178178
dt = sqrt(dt2) # save
179179
Cx2 = 0.5*Cx2; Cy2 = 0.5*Cy2; dt2 = 0.5*dt2 # redefine
180180
D1 = 1; D2 = 0
181181
else:
182182
D1 = 2; D2 = 1
183183
for i in Ix[1:-1]:
184-
for j in Iy[1:-1]:
184+
for j in It[1:-1]:
185185
u_xx = u_n[i-1,j] - 2*u_n[i,j] + u_n[i+1,j]
186186
u_yy = u_n[i,j-1] - 2*u_n[i,j] + u_n[i,j+1]
187187
u[i,j] = D1*u_n[i,j] - D2*u_nm1[i,j] + \
188188
Cx2*u_xx + Cy2*u_yy + dt2*f(x[i], y[j], t[n])
189189
if step1:
190190
u[i,j] += dt*V(x[i], y[j])
191191
# Boundary condition u=0
192-
j = Iy[0]
192+
j = It[0]
193193
for i in Ix: u[i,j] = 0
194-
j = Iy[-1]
194+
j = It[-1]
195195
for i in Ix: u[i,j] = 0
196196
i = Ix[0]
197-
for j in Iy: u[i,j] = 0
197+
for j in It: u[i,j] = 0
198198
i = Ix[-1]
199-
for j in Iy: u[i,j] = 0
199+
for j in It: u[i,j] = 0
200200
return u
201201

202202
def advance_vectorized(u, u_n, u_nm1, f_a, Cx2, Cy2, dt2,

src/softeng2/wave2D_u0_class.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,14 @@ def solver(I, V, f, c, Lx, Ly, Nx, Ny, dt, T,
8989
f_a = zeros((Nx+1,Ny+1), order=order) # for compiled loops
9090

9191
Ix = range(0, u.shape[0])
92-
Iy = range(0, u.shape[1])
92+
It = range(0, u.shape[1])
9393
It = range(0, t.shape[0])
9494

9595
import time; t0 = time.perf_counter() # for measuring CPU time
9696
# Load initial condition into u_1
9797
if version == 'scalar':
9898
for i in Ix:
99-
for j in Iy:
99+
for j in It:
100100
u_1[i,j] = I(x[i], y[j])
101101
else: # use vectorized version
102102
u_1[:,:] = I(xv, yv)
@@ -158,30 +158,30 @@ def solver(I, V, f, c, Lx, Ly, Nx, Ny, dt, T,
158158

159159
def advance_scalar(u, u_1, u_2, f, x, y, t, n, Cx2, Cy2, dt2,
160160
V=None, step1=False):
161-
Ix = range(0, u.shape[0]); Iy = range(0, u.shape[1])
161+
Ix = range(0, u.shape[0]); It = range(0, u.shape[1])
162162
if step1:
163163
dt = sqrt(dt2) # save
164164
Cx2 = 0.5*Cx2; Cy2 = 0.5*Cy2; dt2 = 0.5*dt2 # redefine
165165
D1 = 1; D2 = 0
166166
else:
167167
D1 = 2; D2 = 1
168168
for i in Ix[1:-1]:
169-
for j in Iy[1:-1]:
169+
for j in It[1:-1]:
170170
u_xx = u_1[i-1,j] - 2*u_1[i,j] + u_1[i+1,j]
171171
u_yy = u_1[i,j-1] - 2*u_1[i,j] + u_1[i,j+1]
172172
u[i,j] = D1*u_1[i,j] - D2*u_2[i,j] + \
173173
Cx2*u_xx + Cy2*u_yy + dt2*f(x[i], y[j], t[n])
174174
if step1:
175175
u[i,j] += dt*V(x[i], y[j])
176176
# Boundary condition u=0
177-
j = Iy[0]
177+
j = It[0]
178178
for i in Ix: u[i,j] = 0
179-
j = Iy[-1]
179+
j = It[-1]
180180
for i in Ix: u[i,j] = 0
181181
i = Ix[0]
182-
for j in Iy: u[i,j] = 0
182+
for j in It: u[i,j] = 0
183183
i = Ix[-1]
184-
for j in Iy: u[i,j] = 0
184+
for j in It: u[i,j] = 0
185185
return u
186186

187187
def advance_vectorized(u, u_1, u_2, f_a, Cx2, Cy2, dt2,

src/softeng2/wave2D_u0_loop_c.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,3 @@ void advance(double* u, double* u_1, double* u_2, double* f,
2020
i = 0; for (j=0; j<=Ny; j++) u[idx(i,j)] = 0;
2121
i = Nx; for (j=0; j<=Ny; j++) u[idx(i,j)] = 0;
2222
}
23-

src/softeng2/wave2D_u0_loop_c_f2py_signature.f

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,3 @@ subroutine advance(u, u_1, u_2, f, Cx2, Cy2, dt2, Nx, Ny)
77
Cf2py intent(c) u, u_1, u_2, f, Cx2, Cy2, dt2, Nx, Ny
88
return
99
end
10-
11-

0 commit comments

Comments
 (0)