|
6 | 6 |
|
7 | 7 | from devito import ( |
8 | 8 | ConditionalDimension, Dimension, Eq, Function, Grid, Operator, SparseTimeFunction, |
9 | | - SubDomain, TimeFunction, solve, switchconfig |
| 9 | + SubDomain, TensorTimeFunction, TimeFunction, VectorTimeFunction, diag, div, grad, |
| 10 | + solve, switchconfig |
10 | 11 | ) |
11 | 12 | from devito.ir.iet.visitors import Specializer |
12 | 13 |
|
@@ -262,7 +263,6 @@ def test_diffusion(self, specialize): |
262 | 263 | ('x_m', 'x_M', 'y_m', 'y_M')]) |
263 | 264 | @pytest.mark.parametrize('source', [False, True]) |
264 | 265 | def test_acoustic(self, specialize, source): |
265 | | - # TODO: Add source injection switch |
266 | 266 | grid = Grid(shape=(101, 101)) |
267 | 267 |
|
268 | 268 | u = TimeFunction(name='u', grid=grid, space_order=4, time_order=2) |
@@ -313,4 +313,63 @@ def gaussian_bump(x, y, x0=0, y0=0, sigma=1): |
313 | 313 | else: |
314 | 314 | assert np.isclose(np.linalg.norm(u.data), 10.793053) |
315 | 315 |
|
316 | | - # Elastic-like test (with and without source injection) |
| 316 | + @pytest.mark.parametrize('specialize', |
| 317 | + [('x_m',), |
| 318 | + ('y_M',), |
| 319 | + ('time_m',), |
| 320 | + ('time_m', 'time_M'), |
| 321 | + ('x_m', 'y_M'), |
| 322 | + ('x_m', 'x_M', 'y_m', 'y_M'), |
| 323 | + ('o_x', 'o_y', 'p_src_m', 'p_src_M')]) |
| 324 | + def test_elastic(self, specialize): |
| 325 | + grid = Grid(shape=(101, 101)) |
| 326 | + |
| 327 | + tau = TensorTimeFunction(name='tau', grid=grid, space_order=4) |
| 328 | + v = VectorTimeFunction(name='v', grid=grid, space_order=4) |
| 329 | + |
| 330 | + vp = 1.25 |
| 331 | + vs = 0.75 |
| 332 | + density = 1. |
| 333 | + |
| 334 | + dt = 0.6*min(grid.spacing)/vp |
| 335 | + |
| 336 | + mu = vs**2 * density |
| 337 | + l = (vp**2 * density - 2*mu) |
| 338 | + b = 1/density |
| 339 | + |
| 340 | + pde_v = v.dt - b * div(tau) |
| 341 | + pde_tau = tau.dt - l * diag(div(v.forward)) \ |
| 342 | + - mu * (grad(v.forward) + grad(v.forward).transpose(inner=False)) |
| 343 | + |
| 344 | + u_v = Eq(v.forward, solve(pde_v, v.forward)) |
| 345 | + u_t = Eq(tau.forward, solve(pde_tau, tau.forward)) |
| 346 | + |
| 347 | + src = SparseTimeFunction(name='src', grid=grid, nt=51, npoint=1) |
| 348 | + src.coordinates.data[:] = np.array(grid.extent)/2 |
| 349 | + src.data[:, 0] = np.sin(np.linspace(0, 2*np.pi, 51)) |
| 350 | + |
| 351 | + src_xx = src.inject(field=tau[0, 0].forward, expr=src) |
| 352 | + src_yy = src.inject(field=tau[1, 1].forward, expr=src) |
| 353 | + |
| 354 | + op = Operator([u_v] + [u_t] + src_xx + src_yy) |
| 355 | + |
| 356 | + op.apply(t_M=50, dt=dt) |
| 357 | + |
| 358 | + # Save and reset result |
| 359 | + fields = (tau[0, 0], tau[0, 1], tau[1, 1], v[0], v[1]) |
| 360 | + |
| 361 | + checks = {field.name: np.array(field.data) for field in fields} |
| 362 | + |
| 363 | + for field in fields: |
| 364 | + field.data[:] = 0 |
| 365 | + |
| 366 | + op.apply_specialize(t_M=50, dt=dt, specialize=specialize) |
| 367 | + |
| 368 | + for field in fields: |
| 369 | + check = checks[field.name] |
| 370 | + assert np.all(np.isclose(check, field.data)) |
| 371 | + |
| 372 | + norms = (1.333946, 0.4931774, 1.333946, 1.1619346, 1.1619346) |
| 373 | + |
| 374 | + for field, norm in zip(fields, norms, strict=True): |
| 375 | + assert np.isclose(np.linalg.norm(field.data), norm) |
0 commit comments