Skip to content

Commit 33b2896

Browse files
authored
Staggered grids (#73)
1 parent fb4b96f commit 33b2896

4 files changed

Lines changed: 112 additions & 4 deletions

File tree

.github/workflows/pytest-petsc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ jobs:
7979
run: |
8080
${{ env.RUN_CMD }} mpiexec -n 1 pytest --cov --cov-config=.coveragerc --cov-report=xml ${{ env.TESTS }}
8181
82+
- name: Test examples
83+
run: |
84+
${{ env.RUN_CMD }} mpiexec -n 1 python3 --cov --cov-config=.coveragerc --cov-report=xml examples/petsc/seismic/staggered_acoustic.py
85+
8286
- name: Upload coverage to Codecov
8387
if: "!contains(matrix.name, 'docker')"
8488
uses: codecov/codecov-action@v4

devito/petsc/iet/routines.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,9 +1373,11 @@ def spatial_body(self):
13731373
spatial_body = []
13741374
# TODO: remove the iters[0]
13751375
for tree in retrieve_iteration_tree(self.iters[0]):
1376-
root = filter_iterations(tree, key=lambda i: i.dim.is_Space)[0]
1377-
if self.injectsolve in FindNodes(PetscMetaData).visit(root):
1378-
spatial_body.append(root)
1376+
root = filter_iterations(tree, key=lambda i: i.dim.is_Space)
1377+
if root:
1378+
root = root[0]
1379+
if self.injectsolve in FindNodes(PetscMetaData).visit(root):
1380+
spatial_body.append(root)
13791381
spatial_body, = spatial_body
13801382
return spatial_body
13811383

devito/petsc/types/array.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ def __dtype_setup__(cls, **kwargs):
5959

6060
@classmethod
6161
def __indices_setup__(cls, *args, **kwargs):
62-
dimensions = kwargs['target'].space_dimensions
62+
target = kwargs['target']
63+
dimensions = tuple(target.indices[d] for d in target.space_dimensions)
6364
if args:
6465
indices = args
6566
else:
@@ -92,6 +93,10 @@ def shape(self):
9293
def space_order(self):
9394
return self.target.space_order
9495

96+
@property
97+
def is_Staggered(self):
98+
return self.target.staggered is not None
99+
95100
@property
96101
def localinfo(self):
97102
return self._localinfo
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from devito import *
2+
import os
3+
import numpy as np
4+
from examples.seismic.source import DGaussSource, TimeAxis
5+
from devito.petsc import PETScSolve
6+
from devito.petsc.initialize import PetscInitialize
7+
configuration['compiler'] = 'custom'
8+
os.environ['CC'] = 'mpicc'
9+
10+
11+
# PETSc implementation of devito/examples/seismic/tutorials/05_staggered_acoustic.ipynb
12+
# Test staggered grid implementation with PETSc
13+
14+
PetscInitialize()
15+
16+
extent = (2000., 2000.)
17+
shape = (81, 81)
18+
19+
x = SpaceDimension(
20+
name='x', spacing=Constant(name='h_x', value=extent[0]/(shape[0]-1), dtype=np.float64)
21+
)
22+
z = SpaceDimension(
23+
name='z', spacing=Constant(name='h_z', value=extent[1]/(shape[1]-1), dtype=np.float64)
24+
)
25+
26+
grid = Grid(extent=extent, shape=shape, dimensions=(x, z), dtype=np.float64)
27+
28+
# Timestep size
29+
t0, tn = 0., 200.
30+
dt = 1e2*(1. / np.sqrt(2.)) / 60.
31+
time_range = TimeAxis(start=t0, stop=tn, step=dt)
32+
33+
src = DGaussSource(name='src', grid=grid, f0=0.01, time_range=time_range, a=0.004)
34+
src.coordinates.data[:] = [1000., 1000.]
35+
36+
# Now we create the velocity and pressure fields
37+
# NOTE/TODO: PETSc does not yet fully support VectorTimeFunctions. Ideally,
38+
# it should use the new "coupled" machinery
39+
p2 = TimeFunction(name='p2', grid=grid, staggered=NODE, space_order=2, time_order=1)
40+
vx2 = TimeFunction(name='vx2', grid=grid, staggered=(x,), space_order=2, time_order=1)
41+
vz2 = TimeFunction(name='vz2', grid=grid, staggered=(z,), space_order=2, time_order=1)
42+
43+
t = grid.stepping_dim
44+
time = grid.time_dim
45+
46+
# We need some initial conditions
47+
V_p = 4.0
48+
density = 1.
49+
50+
ro = 1/density
51+
l2m = V_p*V_p*density
52+
53+
# The source injection term
54+
src_p_2 = src.inject(field=p2.forward, expr=src)
55+
56+
# 2nd order acoustic according to fdelmoc
57+
v_x_2 = Eq(vx2.dt, ro * p2.dx)
58+
v_z_2 = Eq(vz2.dt, ro * p2.dz)
59+
60+
petsc_v_x_2 = PETScSolve(v_x_2, target=vx2.forward)
61+
petsc_v_z_2 = PETScSolve(v_z_2, target=vz2.forward)
62+
63+
p_2 = Eq(p2.dt, l2m * (vx2.forward.dx + vz2.forward.dz))
64+
65+
petsc_p_2 = PETScSolve(p_2, target=p2.forward, solver_parameters={'ksp_rtol': 1e-7})
66+
67+
with switchconfig(language='petsc'):
68+
op_2 = Operator(petsc_v_x_2 + petsc_v_z_2 + petsc_p_2 + src_p_2, opt='noop')
69+
op_2(time=src.time_range.num-1, dt=dt)
70+
71+
norm_p2 = norm(p2)
72+
assert np.isclose(norm_p2, .35098, atol=1e-4, rtol=0)
73+
74+
75+
# 4th order acoustic according to fdelmoc
76+
p4 = TimeFunction(name='p4', grid=grid, staggered=NODE, space_order=4)
77+
vx4 = TimeFunction(name='vx4', grid=grid, staggered=(x,), space_order=4, time_order=1)
78+
vz4 = TimeFunction(name='vz4', grid=grid, staggered=(z,), space_order=4, time_order=1)
79+
80+
src_p_4 = src.inject(field=p4.forward, expr=src)
81+
82+
v_x_4 = Eq(vx4.dt, ro * p4.dx)
83+
v_z_4 = Eq(vz4.dt, ro * p4.dz)
84+
85+
petsc_v_x_4 = PETScSolve(v_x_4, target=vx4.forward)
86+
petsc_v_z_4 = PETScSolve(v_z_4, target=vz4.forward)
87+
88+
p_4 = Eq(p4.dt, l2m * (vx4.forward.dx + vz4.forward.dz))
89+
90+
petsc_p_4 = PETScSolve(p_4, target=p4.forward, solver_parameters={'ksp_rtol': 1e-7})
91+
92+
with switchconfig(language='petsc'):
93+
op_4 = Operator(petsc_v_x_4 + petsc_v_z_4 + petsc_p_4 + src_p_4, opt='noop')
94+
op_4(time=src.time_range.num-1, dt=dt)
95+
96+
norm_p4 = norm(p4)
97+
assert np.isclose(norm_p4, .33736, atol=1e-4, rtol=0)

0 commit comments

Comments
 (0)