def boundary_faces(self): """Boundary face locations This property returns the locations of the faces on the boundary of the mesh as a numpy array. The shape of the numpy array is the number of boundary faces by the dimension of the mesh. Returns ------- (n_boundary_faces, dim) numpy.ndarray of float Boundary faces locations """ dim = self.dim if dim == 1: return self.nodes_x[[0, -1]] if dim == 2: fx = ndgrid(self.nodes_x[[0, -1]], self.cell_centers_y) fy = ndgrid(self.cell_centers_x, self.nodes_y[[0, -1]]) return np.r_[fx, fy] if dim == 3: fx = ndgrid(self.nodes_x[[0, -1]], self.cell_centers_y, self.cell_centers_z) fy = ndgrid(self.cell_centers_x, self.nodes_y[[0, -1]], self.cell_centers_z) fz = ndgrid(self.cell_centers_x, self.cell_centers_y, self.nodes_z[[0, -1]]) return np.r_[fx, fy, fz]
def boundary_face_outward_normals(self): dim = self.dim if dim == 1: return np.array([-1, 1]) if dim == 2: nx = ndgrid(np.r_[-1, 1], np.zeros(self.shape_cells[1])) ny = ndgrid(np.zeros(self.shape_cells[0]), np.r_[-1, 1]) return np.r_[nx, ny] if dim == 3: nx = ndgrid( np.r_[-1, 1], np.zeros(self.shape_cells[1]), np.zeros(self.shape_cells[2]), ) ny = ndgrid( np.zeros(self.shape_cells[0]), np.r_[-1, 1], np.zeros(self.shape_cells[2]), ) nz = ndgrid( np.zeros(self.shape_cells[0]), np.zeros(self.shape_cells[1]), np.r_[-1, 1], ) return np.r_[nx, ny, nz]
def boundary_edges(self): """Boundary edge locations This property returns the locations of the edges on the boundary of the mesh as a numpy array. The shape of the numpy array is the number of boundary edges by the dimension of the mesh. Returns ------- (n_boundary_edges, dim) numpy.ndarray of float Boundary edge locations """ dim = self.dim if dim == 1: return None # no boundary edges in 1D if dim == 2: ex = ndgrid(self.cell_centers_x, self.nodes_y[[0, -1]]) ey = ndgrid(self.nodes_x[[0, -1]], self.cell_centers_y) return np.r_[ex, ey] if dim == 3: ex = self.edges_x[make_boundary_bool(self.shape_edges_x, dir="yz")] ey = self.edges_y[make_boundary_bool(self.shape_edges_y, dir="xz")] ez = self.edges_z[make_boundary_bool(self.shape_edges_z, dir="xy")] return np.r_[ex, ey, ez]
def setUp(self): a = np.array([1, 1, 1]) b = np.array([1, 2]) c = np.array([1, 4]) def gridIt(h): return [np.cumsum(np.r_[0, x]) for x in h] X, Y = ndgrid(gridIt([a, b]), vector=False) self.TM2 = TensorMesh([a, b]) self.Curv2 = CurvilinearMesh([X, Y]) X, Y, Z = ndgrid(gridIt([a, b, c]), vector=False) self.TM3 = TensorMesh([a, b, c]) self.Curv3 = CurvilinearMesh([X, Y, Z])
def h_gridded(self): """ Returns an (nC, dim) numpy array with the widths of all cells in order """ if self.dim == 1: return self.h[0][:, None] return ndgrid(*self.h)
def _getEdgePxx(M): i, j = np.arange(M.nCx), np.arange(M.nCy) iijj = ndgrid(i, j) ii, jj = iijj[:, 0], iijj[:, 1] if M._meshType == 'Curv': eT1 = M.r(M.tangents, 'E', 'Ex', 'M') eT2 = M.r(M.tangents, 'E', 'Ey', 'M') def Pxx(xEdge, yEdge): """ no | node | e1 | e2 00 | i ,j | i ,j | i ,j 10 | i+1,j | i ,j | i+1,j 01 | i ,j+1 | i ,j+1 | i ,j 11 | i+1,j+1 | i ,j+1 | i+1,j """ posX = 0 if xEdge == 'eX0' else 1 posY = 0 if yEdge == 'eY0' else 1 ind1 = sub2ind(M.vnEx, np.c_[ii, jj + posX]) ind2 = sub2ind(M.vnEy, np.c_[ii + posY, jj]) + M.nEx IND = np.r_[ind1, ind2].flatten() PXX = sp.coo_matrix((np.ones(2*M.nC), (range(2*M.nC), IND)), shape=(2*M.nC, M.nE)).tocsr() if M._meshType == 'Curv': I2x2 = inv2X2BlockDiagonal(getSubArray(eT1[0], [i, j + posX]), getSubArray(eT1[1], [i, j + posX]), getSubArray(eT2[0], [i + posY, j]), getSubArray(eT2[1], [i + posY, j])) PXX = I2x2 * PXX return PXX return Pxx
def boundary_faces(self): dim = self.dim if dim == 1: return self.nodes_x[[0, -1]] if dim == 2: fx = ndgrid(self.nodes_x[[0, -1]], self.cell_centers_y) fy = ndgrid(self.cell_centers_x, self.nodes_y[[0, -1]]) return np.r_[fx, fy] if dim == 3: fx = ndgrid(self.nodes_x[[0, -1]], self.cell_centers_y, self.cell_centers_z) fy = ndgrid(self.cell_centers_x, self.nodes_y[[0, -1]], self.cell_centers_z) fz = ndgrid(self.cell_centers_x, self.cell_centers_y, self.nodes_z[[0, -1]]) return np.r_[fx, fy, fz]
def test_ndgrid_2D(self): XY = ndgrid([self.a, self.b]) X1_test = np.array([1, 2, 3, 1, 2, 3]) X2_test = np.array([1, 1, 1, 2, 2, 2]) self.assertTrue(np.all(XY[:, 0] == X1_test)) self.assertTrue(np.all(XY[:, 1] == X2_test))
def _getFacePxxx(M): """returns a function for creating projection matrices Mats takes you from faces a subset of all faces on only the faces that you ask for. These are centered around a single nodes. """ i, j, k = np.arange(M.nCx), np.arange(M.nCy), np.arange(M.nCz) iijjkk = ndgrid(i, j, k) ii, jj, kk = iijjkk[:, 0], iijjkk[:, 1], iijjkk[:, 2] if M._meshType == 'Curv': fN1 = M.r(M.normals, 'F', 'Fx', 'M') fN2 = M.r(M.normals, 'F', 'Fy', 'M') fN3 = M.r(M.normals, 'F', 'Fz', 'M') def Pxxx(xFace, yFace, zFace): """ xFace is 'fXp' or 'fXm' yFace is 'fYp' or 'fYm' zFace is 'fZp' or 'fZm' """ # no | node | f1 | f2 | f3 # 000 | i ,j ,k | i , j, k | i, j , k | i, j, k # 100 | i+1,j ,k | i+1, j, k | i, j , k | i, j, k # 010 | i ,j+1,k | i , j, k | i, j+1, k | i, j, k # 110 | i+1,j+1,k | i+1, j, k | i, j+1, k | i, j, k # 001 | i ,j ,k+1 | i , j, k | i, j , k | i, j, k+1 # 101 | i+1,j ,k+1 | i+1, j, k | i, j , k | i, j, k+1 # 011 | i ,j+1,k+1 | i , j, k | i, j+1, k | i, j, k+1 # 111 | i+1,j+1,k+1 | i+1, j, k | i, j+1, k | i, j, k+1 posX = 0 if xFace == 'fXm' else 1 posY = 0 if yFace == 'fYm' else 1 posZ = 0 if zFace == 'fZm' else 1 ind1 = sub2ind(M.vnFx, np.c_[ii + posX, jj, kk]) ind2 = sub2ind(M.vnFy, np.c_[ii, jj + posY, kk]) + M.nFx ind3 = sub2ind(M.vnFz, np.c_[ii, jj, kk + posZ]) + M.nFx + M.nFy IND = np.r_[ind1, ind2, ind3].flatten() PXXX = sp.coo_matrix((np.ones(3*M.nC), (range(3*M.nC), IND)), shape=(3*M.nC, M.nF)).tocsr() if M._meshType == 'Curv': I3x3 = inv3X3BlockDiagonal(getSubArray(fN1[0], [i + posX, j, k]), getSubArray(fN1[1], [i + posX, j, k]), getSubArray(fN1[2], [i + posX, j, k]), getSubArray(fN2[0], [i, j + posY, k]), getSubArray(fN2[1], [i, j + posY, k]), getSubArray(fN2[2], [i, j + posY, k]), getSubArray(fN3[0], [i, j, k + posZ]), getSubArray(fN3[1], [i, j, k + posZ]), getSubArray(fN3[2], [i, j, k + posZ])) PXXX = I3x3 * PXXX return PXXX return Pxxx
def test_ndgrid_3D(self): XYZ = ndgrid([self.a, self.b, self.c]) X1_test = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]) X2_test = np.array([1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2]) X3_test = np.array([1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4]) self.assertTrue(np.all(XYZ[:, 0] == X1_test)) self.assertTrue(np.all(XYZ[:, 1] == X2_test)) self.assertTrue(np.all(XYZ[:, 2] == X3_test))
def boundary_face_outward_normals(self): """Outward normal vectors of boundary faces This property returns the outward normal vectors of faces the boundary of the mesh as a numpy array. The shape of the numpy array is the number of boundary faces by the dimension of the mesh. Returns ------- (n_boundary_faces, dim) numpy.ndarray of float Outward normal vectors of boundary faces """ dim = self.dim if dim == 1: return np.array([-1, 1]) if dim == 2: nx = ndgrid(np.r_[-1, 1], np.zeros(self.shape_cells[1])) ny = ndgrid(np.zeros(self.shape_cells[0]), np.r_[-1, 1]) return np.r_[nx, ny] if dim == 3: nx = ndgrid( np.r_[-1, 1], np.zeros(self.shape_cells[1]), np.zeros(self.shape_cells[2]), ) ny = ndgrid( np.zeros(self.shape_cells[0]), np.r_[-1, 1], np.zeros(self.shape_cells[2]), ) nz = ndgrid( np.zeros(self.shape_cells[0]), np.zeros(self.shape_cells[1]), np.r_[-1, 1], ) return np.r_[nx, ny, nz]
def h_gridded(self): """Return dimensions of all mesh cells as staggered grid. This property returns a numpy array of shape (n_cells, dim) containing gridded x, (y and z) dimensions for all cells in the mesh. The first row corresponds to the bottom-front-leftmost cell. The cells are ordered along the x, then y, then z directions. Returns ------- (n_cells, dim) numpy.ndarray of float Dimensions of all mesh cells as staggered grid Examples -------- The following is a 1D example. >>> from discretize import TensorMesh >>> hx = np.ones(5) >>> mesh_1D = TensorMesh([hx]) >>> mesh_1D.h_gridded array([[1.], [1.], [1.], [1.], [1.]]) The following is a 3D example. >>> hx, hy, hz = np.ones(2), 2*np.ones(2), 3*np.ones(2) >>> mesh_3D = TensorMesh([hx, hy, hz]) >>> mesh_3D.h_gridded array([[1., 2., 3.], [1., 2., 3.], [1., 2., 3.], [1., 2., 3.], [1., 2., 3.], [1., 2., 3.], [1., 2., 3.], [1., 2., 3.]]) """ if self.dim == 1: return self.h[0][:, None] return ndgrid(*self.h)
def _getEdgePxxx(M): i, j, k = np.arange(M.nCx), np.arange(M.nCy), np.arange(M.nCz) iijjkk = ndgrid(i, j, k) ii, jj, kk = iijjkk[:, 0], iijjkk[:, 1], iijjkk[:, 2] if M._meshType == 'Curv': eT1 = M.r(M.tangents, 'E', 'Ex', 'M') eT2 = M.r(M.tangents, 'E', 'Ey', 'M') eT3 = M.r(M.tangents, 'E', 'Ez', 'M') def Pxxx(xEdge, yEdge, zEdge): """ no | node | e1 | e2 | e3 000 | i ,j ,k | i ,j ,k | i ,j ,k | i ,j ,k 100 | i+1,j ,k | i ,j ,k | i+1,j ,k | i+1,j ,k 010 | i ,j+1,k | i ,j+1,k | i ,j ,k | i ,j+1,k 110 | i+1,j+1,k | i ,j+1,k | i+1,j ,k | i+1,j+1,k 001 | i ,j ,k+1 | i ,j ,k+1 | i ,j ,k+1 | i ,j ,k 101 | i+1,j ,k+1 | i ,j ,k+1 | i+1,j ,k+1 | i+1,j ,k 011 | i ,j+1,k+1 | i ,j+1,k+1 | i ,j ,k+1 | i ,j+1,k 111 | i+1,j+1,k+1 | i ,j+1,k+1 | i+1,j ,k+1 | i+1,j+1,k """ posX = [0,0] if xEdge == 'eX0' else [1, 0] if xEdge == 'eX1' else [0,1] if xEdge == 'eX2' else [1,1] posY = [0,0] if yEdge == 'eY0' else [1, 0] if yEdge == 'eY1' else [0,1] if yEdge == 'eY2' else [1,1] posZ = [0,0] if zEdge == 'eZ0' else [1, 0] if zEdge == 'eZ1' else [0,1] if zEdge == 'eZ2' else [1,1] ind1 = sub2ind(M.vnEx, np.c_[ii, jj + posX[0], kk + posX[1]]) ind2 = sub2ind(M.vnEy, np.c_[ii + posY[0], jj, kk + posY[1]]) + M.nEx ind3 = sub2ind(M.vnEz, np.c_[ii + posZ[0], jj + posZ[1], kk]) + M.nEx + M.nEy IND = np.r_[ind1, ind2, ind3].flatten() PXXX = sp.coo_matrix((np.ones(3*M.nC), (range(3*M.nC), IND)), shape=(3*M.nC, M.nE)).tocsr() if M._meshType == 'Curv': I3x3 = inv3X3BlockDiagonal(getSubArray(eT1[0], [i, j + posX[0], k + posX[1]]), getSubArray(eT1[1], [i, j + posX[0], k + posX[1]]), getSubArray(eT1[2], [i, j + posX[0], k + posX[1]]), getSubArray(eT2[0], [i + posY[0], j, k + posY[1]]), getSubArray(eT2[1], [i + posY[0], j, k + posY[1]]), getSubArray(eT2[2], [i + posY[0], j, k + posY[1]]), getSubArray(eT3[0], [i + posZ[0], j + posZ[1], k]), getSubArray(eT3[1], [i + posZ[0], j + posZ[1], k]), getSubArray(eT3[2], [i + posZ[0], j + posZ[1], k])) PXXX = I3x3 * PXXX return PXXX return Pxxx
def _getEdgePxx(M): i, j = np.arange(M.shape_cells[0]), np.arange(M.shape_cells[1]) iijj = ndgrid(i, j) ii, jj = iijj[:, 0], iijj[:, 1] if M._meshType == "Curv": eT1 = M.reshape(M.edge_tangents, "E", "Ex", "M") eT2 = M.reshape(M.edge_tangents, "E", "Ey", "M") def Pxx(xEdge, yEdge): """ no | node | e1 | e2 00 | i ,j | i ,j | i ,j 10 | i+1,j | i ,j | i+1,j 01 | i ,j+1 | i ,j+1 | i ,j 11 | i+1,j+1 | i ,j+1 | i+1,j """ posX = 0 if xEdge == "eX0" else 1 posY = 0 if yEdge == "eY0" else 1 ind1 = sub2ind(M.vnEx, np.c_[ii, jj + posX]) ind2 = sub2ind(M.vnEy, np.c_[ii + posY, jj]) + M.nEx IND = np.r_[ind1, ind2].flatten() PXX = sp.coo_matrix((np.ones(2 * M.nC), (range(2 * M.nC), IND)), shape=(2 * M.nC, M.nE)).tocsr() if M._meshType == "Curv": I2x2 = inverse_2x2_block_diagonal( get_subarray(eT1[0], [i, j + posX]), get_subarray(eT1[1], [i, j + posX]), get_subarray(eT2[0], [i + posY, j]), get_subarray(eT2[1], [i + posY, j]), ) PXX = I2x2 * PXX return PXX return Pxx
def test_active_from_xyz(self): # Create 3D topo [xx, yy] = np.meshgrid(np.linspace(-200, 200, 50), np.linspace(-200, 200, 50)) b = 50 A = 50 zz = A * np.exp(-0.5 * ((xx / b) ** 2. + (yy / b) ** 2.)) h = [5., 5., 5.] # Test 1D Mesh topo1D = zz[25, :].ravel() mesh1D = discretize.TensorMesh( [np.ones(10) * 20], x0='C' ) indtopoCC = active_from_xyz(mesh1D, topo1D, grid_reference='CC', method='nearest') indtopoN = active_from_xyz(mesh1D, topo1D, grid_reference='N', method='nearest') self.assertEqual(indtopoCC.sum(), 3) self.assertEqual(indtopoN.sum(), 2) # Test 2D Tensor mesh topo2D = np.c_[xx[25, :].ravel(), zz[25, :].ravel()] mesh_tensor = discretize.TensorMesh([ [(h[0], 24)], [(h[1], 20)] ], x0='CC') indtopoCC = active_from_xyz(mesh_tensor, topo2D, grid_reference='CC', method='nearest') indtopoN = active_from_xyz(mesh_tensor, topo2D, grid_reference='N', method='nearest') self.assertEqual(indtopoCC.sum(), 434) self.assertEqual(indtopoN.sum(), 412) # Test 2D Tree mesh mesh_tree = mesh_builder_xyz(topo2D, h[:2], mesh_type='TREE') mesh_tree = refine_tree_xyz( mesh_tree, topo2D, method="surface", octree_levels=[1], octree_levels_padding=None, finalize=True ) indtopoCC = active_from_xyz(mesh_tree, topo2D, grid_reference='CC', method='nearest') indtopoN = active_from_xyz(mesh_tree, topo2D, grid_reference='N', method='nearest') self.assertEqual(indtopoCC.sum(), 167) self.assertEqual(indtopoN.sum(), 119) # Test 3D Tensor meshes topo3D = np.c_[xx.ravel(), yy.ravel(), zz.ravel()] mesh_tensor = discretize.TensorMesh([ [(h[0], 24)], [(h[1], 20)], [(h[2], 30)] ], x0='CCC') indtopoCC = active_from_xyz(mesh_tensor, topo3D, grid_reference='CC', method='nearest') indtopoN = active_from_xyz(mesh_tensor, topo3D, grid_reference='N', method='nearest') self.assertEqual(indtopoCC.sum(), 10496) self.assertEqual(indtopoN.sum(), 10084) # Test 3D Tree mesh mesh_tree = mesh_builder_xyz(topo3D, h, mesh_type='TREE') mesh_tree = refine_tree_xyz( mesh_tree, topo3D, method="surface", octree_levels=[1], octree_levels_padding=None, finalize=True ) indtopoCC = active_from_xyz(mesh_tree, topo3D, grid_reference='CC', method='nearest') indtopoN = active_from_xyz(mesh_tree, topo3D, grid_reference='N', method='nearest') self.assertEqual(indtopoCC.sum(), 6299) self.assertEqual(indtopoN.sum(), 4639) # Test 3D CYL Mesh ncr = 10 # number of mesh cells in r ncz = 15 # number of mesh cells in z dr = 15 # cell width r dz = 10 # cell width z npad_r = 4 # number of padding cells in r npad_z = 4 # number of padding cells in z exp_r = 1.25 # expansion rate of padding cells in r exp_z = 1.25 # expansion rate of padding cells in z hr = [(dr, ncr), (dr, npad_r, exp_r)] hz = [(dz, npad_z, -exp_z), (dz, ncz), (dz, npad_z, exp_z)] # A value of 1 is used to define the discretization in phi for this case. mesh_cyl = discretize.CylMesh([hr, 1, hz], x0='00C') indtopoCC = active_from_xyz(mesh_cyl, topo3D, grid_reference='CC', method='nearest') indtopoN = active_from_xyz(mesh_cyl, topo3D, grid_reference='N', method='nearest') self.assertEqual(indtopoCC.sum(), 183) self.assertEqual(indtopoN.sum(), 171) htheta = meshTensor([(1., 4)]) htheta = htheta * 2*np.pi / htheta.sum() mesh_cyl2 = discretize.CylMesh([hr, htheta, hz], x0='00C') with self.assertRaises(NotImplementedError): indtopoCC = active_from_xyz(mesh_cyl2, topo3D, grid_reference='CC', method='nearest') def gridIt(h): return [np.cumsum(np.r_[0, x]) for x in h] X, Y = ndgrid(gridIt([[5.]*24, [5.]*20]), vector=False) mesh_curvi = discretize.CurvilinearMesh([X, Y]) with self.assertRaises(TypeError): indTopoCC = active_from_xyz(mesh_curvi, topo3D, grid_reference='CC', method='nearest')
def _getFacePxx(M): """returns a function for creating projection matrices Mats takes you from faces a subset of all faces on only the faces that you ask for. These are centered around a single nodes. For example, if this was your entire mesh: f3(Yp) 2_______________3 | | | | | | f0(Xm) | x | f1(Xp) | | | | |_______________| 0 1 f2(Ym) Pxx('fXm','fYm') = | 1, 0, 0, 0 | | 0, 0, 1, 0 | Pxx('fXp','fYm') = | 0, 1, 0, 0 | | 0, 0, 1, 0 | """ i, j = np.arange(M.nCx), np.arange(M.nCy) iijj = ndgrid(i, j) ii, jj = iijj[:, 0], iijj[:, 1] if M._meshType == 'Curv': fN1 = M.r(M.normals, 'F', 'Fx', 'M') fN2 = M.r(M.normals, 'F', 'Fy', 'M') def Pxx(xFace, yFace): """ xFace is 'fXp' or 'fXm' yFace is 'fYp' or 'fYm' """ # no | node | f1 | f2 # 00 | i ,j | i , j | i, j # 10 | i+1,j | i+1, j | i, j # 01 | i ,j+1 | i , j | i, j+1 # 11 | i+1,j+1 | i+1, j | i, j+1 posFx = 0 if xFace == 'fXm' else 1 posFy = 0 if yFace == 'fYm' else 1 ind1 = sub2ind(M.vnFx, np.c_[ii + posFx, jj]) ind2 = sub2ind(M.vnFy, np.c_[ii, jj + posFy]) + M.nFx IND = np.r_[ind1, ind2].flatten() PXX = sp.csr_matrix((np.ones(2 * M.nC), (range(2 * M.nC), IND)), shape=(2 * M.nC, M.nF)) if M._meshType == 'Curv': I2x2 = inv2X2BlockDiagonal(getSubArray(fN1[0], [i + posFx, j]), getSubArray(fN1[1], [i + posFx, j]), getSubArray(fN2[0], [i, j + posFy]), getSubArray(fN2[1], [i, j + posFy])) PXX = I2x2 * PXX return PXX return Pxx
def _getTensorGrid(self, key): if getattr(self, "_" + key, None) is None: setattr(self, "_" + key, ndgrid(self.get_tensor(key))) return getattr(self, "_" + key)
def _getTensorGrid(self, key): if getattr(self, '_grid' + key, None) is None: setattr(self, '_grid' + key, utils.ndgrid(self.getTensor(key))) return getattr(self, '_grid' + key)
def _getEdgePxxx(M): i, j, k = ( np.arange(M.shape_cells[0]), np.arange(M.shape_cells[1]), np.arange(M.shape_cells[2]), ) iijjkk = ndgrid(i, j, k) ii, jj, kk = iijjkk[:, 0], iijjkk[:, 1], iijjkk[:, 2] if M._meshType == "Curv": eT1 = M.reshape(M.edge_tangents, "E", "Ex", "M") eT2 = M.reshape(M.edge_tangents, "E", "Ey", "M") eT3 = M.reshape(M.edge_tangents, "E", "Ez", "M") def Pxxx(xEdge, yEdge, zEdge): """ no | node | e1 | e2 | e3 000 | i ,j ,k | i ,j ,k | i ,j ,k | i ,j ,k 100 | i+1,j ,k | i ,j ,k | i+1,j ,k | i+1,j ,k 010 | i ,j+1,k | i ,j+1,k | i ,j ,k | i ,j+1,k 110 | i+1,j+1,k | i ,j+1,k | i+1,j ,k | i+1,j+1,k 001 | i ,j ,k+1 | i ,j ,k+1 | i ,j ,k+1 | i ,j ,k 101 | i+1,j ,k+1 | i ,j ,k+1 | i+1,j ,k+1 | i+1,j ,k 011 | i ,j+1,k+1 | i ,j+1,k+1 | i ,j ,k+1 | i ,j+1,k 111 | i+1,j+1,k+1 | i ,j+1,k+1 | i+1,j ,k+1 | i+1,j+1,k """ posX = ([0, 0] if xEdge == "eX0" else [1, 0] if xEdge == "eX1" else [0, 1] if xEdge == "eX2" else [1, 1]) posY = ([0, 0] if yEdge == "eY0" else [1, 0] if yEdge == "eY1" else [0, 1] if yEdge == "eY2" else [1, 1]) posZ = ([0, 0] if zEdge == "eZ0" else [1, 0] if zEdge == "eZ1" else [0, 1] if zEdge == "eZ2" else [1, 1]) ind1 = sub2ind(M.vnEx, np.c_[ii, jj + posX[0], kk + posX[1]]) ind2 = sub2ind(M.vnEy, np.c_[ii + posY[0], jj, kk + posY[1]]) + M.nEx ind3 = (sub2ind(M.vnEz, np.c_[ii + posZ[0], jj + posZ[1], kk]) + M.nEx + M.nEy) IND = np.r_[ind1, ind2, ind3].flatten() PXXX = sp.coo_matrix((np.ones(3 * M.nC), (range(3 * M.nC), IND)), shape=(3 * M.nC, M.nE)).tocsr() if M._meshType == "Curv": I3x3 = inverse_3x3_block_diagonal( get_subarray(eT1[0], [i, j + posX[0], k + posX[1]]), get_subarray(eT1[1], [i, j + posX[0], k + posX[1]]), get_subarray(eT1[2], [i, j + posX[0], k + posX[1]]), get_subarray(eT2[0], [i + posY[0], j, k + posY[1]]), get_subarray(eT2[1], [i + posY[0], j, k + posY[1]]), get_subarray(eT2[2], [i + posY[0], j, k + posY[1]]), get_subarray(eT3[0], [i + posZ[0], j + posZ[1], k]), get_subarray(eT3[1], [i + posZ[0], j + posZ[1], k]), get_subarray(eT3[2], [i + posZ[0], j + posZ[1], k]), ) PXXX = I3x3 * PXXX return PXXX return Pxxx