|
3 | 3 | import numpy as np |
4 | 4 | import scipy.sparse as sp |
5 | 5 | from scipy.spatial import KDTree |
6 | | -from discretize.utils import Identity, invert_blocks, spzeros |
| 6 | +from discretize.utils import Identity, invert_blocks, spzeros, cross2d |
7 | 7 | from discretize.base import BaseMesh |
8 | 8 | from discretize._extensions.simplex_helpers import ( |
9 | 9 | _build_faces_edges, |
@@ -264,7 +264,7 @@ def face_normals(self): # NOQA D102 |
264 | 264 | if self.dim == 2: |
265 | 265 | # Take the normal as being the cross product of edge_tangents |
266 | 266 | # and a unit vector in a "3rd" dimension. |
267 | | - normal = np.cross(self.edge_tangents, [0, 0, 1])[:, :-1] |
| 267 | + normal = np.c_[self.edge_tangents[:, 1], -self.edge_tangents[:, 0]] |
268 | 268 | else: |
269 | 269 | # define normal as |01 x 02| |
270 | 270 | # therefore clockwise path about the normal is 0->1->2->0 |
@@ -346,7 +346,7 @@ def edge_curl(self): # NOQA D102 |
346 | 346 | # cp = np.cross(l01, -l20) |
347 | 347 | # cp is a bunch of 1s (where simplices are CCW) and -1s (where simplices are CW) |
348 | 348 | # (but we take the sign here to guard against numerical precision) |
349 | | - cp = np.sign(np.cross(l20, l01)) |
| 349 | + cp = np.sign(cross2d(l20, l01)) |
350 | 350 | face_areas = face_areas * cp |
351 | 351 | # don't due *= here |
352 | 352 |
|
@@ -812,29 +812,34 @@ def get_interpolation_matrix( # NOQA D102 |
812 | 812 | n_items = self.n_edges |
813 | 813 | elif location_type[:-2] == "faces": |
814 | 814 | # grab the barycentric transforms associated with each simplex: |
815 | | - ts = transform[ |
816 | | - inds, |
817 | | - :, |
818 | | - ] |
| 815 | + ts = transform[inds, :] |
819 | 816 | ts = np.hstack((ts, -ts.sum(axis=1)[:, None])) |
820 | 817 | # use Whitney 2 - form basis functions for face vector interp |
821 | 818 | faces = self._simplex_faces[inds] |
822 | 819 | areas = self.face_areas |
823 | 820 |
|
824 | 821 | # [1, 2], [0, 2], [0, 1] |
825 | 822 | if self.dim == 2: |
| 823 | + # i j k |
| 824 | + # t0 t1 t2 |
| 825 | + # 0 0 1 |
| 826 | + # t1 * i - t0 * j |
| 827 | + |
826 | 828 | f0 = ( |
827 | | - barys[:, 1] * (np.cross(ts[:, 2], [0, 0, 1])[:, i_dir]) |
828 | | - + barys[:, 2] * (np.cross([0, 0, 1], ts[:, 1])[:, i_dir]) |
829 | | - ) * areas[faces[:, 0]] |
| 829 | + cross2d(barys[:, 1:], ts[:, 1:, 1 - i_dir]) * areas[faces[:, 0]] |
| 830 | + ) |
830 | 831 | f1 = ( |
831 | | - barys[:, 0] * (np.cross(ts[:, 2], [0, 0, 1])[:, i_dir]) |
832 | | - + barys[:, 2] * (np.cross([0, 0, 1], ts[:, 0])[:, i_dir]) |
833 | | - ) * areas[faces[:, 1]] |
| 832 | + cross2d(barys[:, [0, 2]], ts[:, [0, 2], 1 - i_dir]) |
| 833 | + * areas[faces[:, 1]] |
| 834 | + ) |
834 | 835 | f2 = ( |
835 | | - barys[:, 0] * (np.cross(ts[:, 1], [0, 0, 1])[:, i_dir]) |
836 | | - + barys[:, 1] * (np.cross([0, 0, 1], ts[:, 0])[:, i_dir]) |
837 | | - ) * areas[faces[:, 2]] |
| 836 | + cross2d(barys[:, :-1], ts[:, :-1, 1 - i_dir]) |
| 837 | + * areas[faces[:, 2]] |
| 838 | + ) |
| 839 | + if i_dir == 1: |
| 840 | + f0 *= -1 |
| 841 | + f1 *= -1 |
| 842 | + f2 *= -1 |
838 | 843 | Aij = np.c_[f0, f1, f2].reshape(-1) |
839 | 844 | ind_ptr = 3 * np.arange(n_loc + 1) |
840 | 845 | else: |
@@ -1219,7 +1224,7 @@ def boundary_edge_vector_integral(self): # NOQA D102 |
1219 | 1224 | Pe = self.project_edge_to_boundary_edge |
1220 | 1225 | n_boundary_edges, n_edges = Pe.shape |
1221 | 1226 | index = boundary_face_edges |
1222 | | - w_cross_n = np.cross(-self.edge_tangents[index], dA) |
| 1227 | + w_cross_n = cross2d(dA, self.edge_tangents[index]) |
1223 | 1228 | M_be = ( |
1224 | 1229 | sp.csr_matrix((w_cross_n, (index, index)), shape=(n_edges, n_edges)) |
1225 | 1230 | @ Pe.T |
|
0 commit comments