|
7 | 7 | import sympy as sp |
8 | 8 |
|
9 | 9 | from devito import Function, VectorFunction, grad, ConditionalDimension, \ |
10 | | - Le, Lt, Gt, Eq, Operator, Grid |
| 10 | + Le, Eq, Operator, Grid |
11 | 11 | from devitoboundary import SDFGenerator |
12 | 12 |
|
13 | 13 | __all__ = ['SignedDistanceFunction', 'AxialDistanceFunction'] |
@@ -76,6 +76,8 @@ class AxialDistanceFunction(SignedDistanceFunction): |
76 | 76 | A class to carry out the calculation of signed distances along each axis |
77 | 77 | from a boundary surface represented by a point cloud or polygon file within |
78 | 78 | 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. |
79 | 81 |
|
80 | 82 | Parameters |
81 | 83 | ---------- |
@@ -147,29 +149,36 @@ def _axial_setup(self): |
147 | 149 | # Only need to calculate adjacent to boundary |
148 | 150 | close_sdf = Le(sp.Abs(pad_sdf), h_x) |
149 | 151 |
|
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 | | - |
158 | 152 | # 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') |
171 | 162 | op_axial.apply() |
172 | 163 |
|
| 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 | + |
173 | 182 | def _pad_grid(self): |
174 | 183 | """ |
175 | 184 | Return a grid with an additional M/2 nodes of padding on each side vs |
|
0 commit comments