Skip to content
This repository was archived by the owner on Feb 21, 2023. It is now read-only.

Commit 6e3bd6b

Browse files
authored
Merge pull request #23 from devitocodes/better_axial_distance
Rework axial distance calculation for greater speed and reliability
2 parents 1105d9a + efb1853 commit 6e3bd6b

1 file changed

Lines changed: 30 additions & 21 deletions

File tree

devitoboundary/distance.py

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import sympy as sp
88

99
from devito import Function, VectorFunction, grad, ConditionalDimension, \
10-
Le, Lt, Gt, Eq, Operator, Grid
10+
Le, Eq, Operator, Grid
1111
from devitoboundary import SDFGenerator
1212

1313
__all__ = ['SignedDistanceFunction', 'AxialDistanceFunction']
@@ -76,6 +76,8 @@ class AxialDistanceFunction(SignedDistanceFunction):
7676
A class to carry out the calculation of signed distances along each axis
7777
from a boundary surface represented by a point cloud or polygon file within
7878
an area of effect determined by the specified set of Devito functions.
79+
Note that unequal grid spacings will cause distances to be calculated where
80+
they shouldn't or vice versa.
7981
8082
Parameters
8183
----------
@@ -147,29 +149,36 @@ def _axial_setup(self):
147149
# Only need to calculate adjacent to boundary
148150
close_sdf = Le(sp.Abs(pad_sdf), h_x)
149151

150-
# Also only want values smaller than one increment
151-
small_x = sp.And(Lt((d - b*pos[1] - c*pos[2])/a - pos[0], h_x),
152-
Gt((d - b*pos[1] - c*pos[2])/a - pos[0], -h_x))
153-
small_y = sp.And(Lt((d - a*pos[0] - c*pos[2])/b - pos[1], h_y),
154-
Gt((d - a*pos[0] - c*pos[2])/b - pos[1], -h_y))
155-
small_z = sp.And(Lt((d - a*pos[0] - b*pos[1])/c - pos[2], h_z),
156-
Gt((d - a*pos[0] - b*pos[1])/c - pos[2], -h_z))
157-
158152
# Conditional mask for calculation
159-
mask_x = ConditionalDimension(name='mask_x', parent=z,
160-
condition=sp.And(close_sdf, small_x))
161-
mask_y = ConditionalDimension(name='mask_y', parent=z,
162-
condition=sp.And(close_sdf, small_y))
163-
mask_z = ConditionalDimension(name='mask_z', parent=z,
164-
condition=sp.And(close_sdf, small_z))
165-
166-
eq_x = Eq(self._axial[0], (d - b*pos[1] - c*pos[2])/a - pos[0], implicit_dims=mask_x)
167-
eq_y = Eq(self._axial[1], (d - a*pos[0] - c*pos[2])/b - pos[1], implicit_dims=mask_y)
168-
eq_z = Eq(self._axial[2], (d - a*pos[0] - b*pos[1])/c - pos[2], implicit_dims=mask_z)
169-
170-
op_axial = Operator([eq_x, eq_y, eq_z], name='Axial')
153+
mask = ConditionalDimension(name='mask', parent=z,
154+
condition=close_sdf)
155+
156+
eq_x = Eq(self._axial[0], (d - b*pos[1] - c*pos[2])/a - pos[0], implicit_dims=mask)
157+
eq_y = Eq(self._axial[1], (d - a*pos[0] - c*pos[2])/b - pos[1], implicit_dims=mask)
158+
eq_z = Eq(self._axial[2], (d - a*pos[0] - b*pos[1])/c - pos[2], implicit_dims=mask)
159+
160+
op_axial = Operator([eq_x, eq_y, eq_z],
161+
name='Axial')
171162
op_axial.apply()
172163

164+
# Deal with silly values x
165+
x_nan_mask = np.isnan(self._axial[0].data)
166+
self._axial[0].data[x_nan_mask] = -self._order*h_x
167+
x_big_mask = np.abs(self._axial[0].data) > h_x
168+
self._axial[0].data[x_big_mask] = -self._order*h_x
169+
170+
# Deal with silly values y
171+
y_nan_mask = np.isnan(self._axial[1].data)
172+
self._axial[1].data[y_nan_mask] = -self._order*h_y
173+
y_big_mask = np.abs(self._axial[1].data) > h_y
174+
self._axial[1].data[y_big_mask] = -self._order*h_y
175+
176+
# Deal with silly values z
177+
z_nan_mask = np.isnan(self._axial[2].data)
178+
self._axial[2].data[z_nan_mask] = -self._order*h_z
179+
z_big_mask = np.abs(self._axial[2].data) > h_z
180+
self._axial[2].data[z_big_mask] = -self._order*h_z
181+
173182
def _pad_grid(self):
174183
"""
175184
Return a grid with an additional M/2 nodes of padding on each side vs

0 commit comments

Comments
 (0)