def construct_matrices(self): """ Construct FEM matrices """ V = p2e(self.vertices) F = p2e(self.faces) # Compute gradient operator: #F*3 by #V G = igl.eigen.SparseMatrixd() L = igl.eigen.SparseMatrixd() M = igl.eigen.SparseMatrixd() N = igl.eigen.MatrixXd() A = igl.eigen.MatrixXd() igl.grad(V, F, G) igl.cotmatrix(V, F, L) igl.per_face_normals(V, F, N) igl.doublearea(V, F, A) igl.massmatrix(V, F, igl.MASSMATRIX_TYPE_VORONOI, M) G = e2p(G) L = e2p(L) N = e2p(N) A = e2p(A) M = e2p(M) M = M.data # Compute latitude and longitude directional vector fields NS = np.reshape(G.dot(self.lat), [self.nf, 3], order='F') EW = np.cross(NS, N) # Compute F2V matrix (weigh by area) # adjacency i = self.faces.ravel() j = np.arange(self.nf).repeat(3) one = np.ones(self.nf * 3) adj = sparse.csc_matrix((one, (i, j)), shape=(self.nv, self.nf)) tot_area = adj.dot(A) norm_area = A.ravel().repeat(3) / np.squeeze(tot_area[i]) F2V = sparse.csc_matrix((norm_area, (i, j)), shape=(self.nv, self.nf)) # Compute interpolation matrix if self.level > 0: intp = self.intp[self.nv_prev:] i = np.concatenate( (np.arange(self.nv), np.arange(self.nv_prev, self.nv))) j = np.concatenate((np.arange(self.nv_prev), intp[:, 0], intp[:, 1])) ratio = np.concatenate( (np.ones(self.nv_prev), 0.5 * np.ones(2 * intp.shape[0]))) intp = sparse.csc_matrix((ratio, (i, j)), shape=(self.nv, self.nv_prev)) else: intp = sparse.csc_matrix(np.eye(self.nv)) # Compute vertex mean matrix self.G = G # gradient matrix self.L = L # laplacian matrix self.N = N # normal vectors (per-triangle) self.NS = NS # north-south vectors (per-triangle) self.EW = EW # east-west vectors (per-triangle) self.F2V = F2V # map face quantities to vertices self.M = M # mass matrix (area of voronoi cell around node. for integration) self.Seq = self._rotseq(self.vertices) self.Intp = intp
V = igl.eigen.MatrixXd() F = igl.eigen.MatrixXi() # Load a mesh in OFF format igl.readOFF(TUTORIAL_SHARED_PATH + "cheburashka.off", V, F) # Read scalar function values from a file, U: #V by 1 U = igl.eigen.MatrixXd() igl.readDMAT(TUTORIAL_SHARED_PATH + "cheburashka-scalar.dmat", U) U = U.col(0) # Compute gradient operator: #F*3 by #V G = igl.eigen.SparseMatrixd() igl.grad(V, F, G) # Compute gradient of U GU = (G * U).MapMatrix(F.rows(), 3) # Compute gradient magnitude GU_mag = GU.rowwiseNorm() viewer = igl.glfw.Viewer() viewer.data().set_mesh(V, F) # Compute pseudocolor for original function C = igl.eigen.MatrixXd() igl.jet(U, True, C)
L = igl.eigen.SparseMatrixd() viewer = igl.viewer.Viewer() # Load a mesh in OFF format igl.readOFF("../../tutorial/shared/cow.off", V, F) # Compute Laplace-Beltrami operator: #V by #V igl.cotmatrix(V,F,L) # Alternative construction of same Laplacian G = igl.eigen.SparseMatrixd() K = igl.eigen.SparseMatrixd() # Gradient/Divergence igl.grad(V,F,G); # Diagonal per-triangle "mass matrix" dblA = igl.eigen.MatrixXd() igl.doublearea(V,F,dblA) # Place areas along diagonal #dim times T = (dblA.replicate(3,1)*0.5).asDiagonal() * 1 # Laplacian K built as discrete divergence of gradient or equivalently # discrete Dirichelet energy Hessian temp = -G.transpose() K = -G.transpose() * T * G print("|K-L|: ",(K-L).norm())
L = igl.eigen.SparseMatrixd() viewer = igl.viewer.Viewer() # Load a mesh in OFF format igl.readOFF("../../tutorial/shared/cow.off", V, F) # Compute Laplace-Beltrami operator: #V by #V igl.cotmatrix(V, F, L) # Alternative construction of same Laplacian G = igl.eigen.SparseMatrixd() K = igl.eigen.SparseMatrixd() # Gradient/Divergence igl.grad(V, F, G) # Diagonal per-triangle "mass matrix" dblA = igl.eigen.MatrixXd() igl.doublearea(V, F, dblA) # Place areas along diagonal #dim times T = (dblA.replicate(3, 1) * 0.5).asDiagonal() * 1 # Laplacian K built as discrete divergence of gradient or equivalently # discrete Dirichelet energy Hessian temp = -G.transpose() K = -G.transpose() * T * G print("|K-L|: ", (K - L).norm())