def facet_length(facet): """ calculate FEniCS facet length """ v_idx = facet.entities(0) v0 = Vertex(facet.mesh(), v_idx[0]) v1 = Vertex(facet.mesh(), v_idx[1]) x0 = v0.point().x() x1 = v1.point().x() y0 = v0.point().y() y1 = v1.point().y() return ((x1 - x0)**2 + (y1 - y0)**2)**0.5
def hat_function_grad(vertex, cell): """Compute L^\infty-norm of gradient of hat function on 'cell' and value 1 in 'vertex'.""" # TODO: fix using ghosted mesh not_working_in_parallel("function 'hat_function_grad'") assert vertex in vertices(cell), "vertex not in cell!" # Find adjacent facet f = [f for f in facets(cell) if not vertex in vertices(f)] assert len(f) == 1, "Something strange with adjacent cell!" f = f[0] # Get unit normal n = f.normal() n /= n.norm() # Pick some vertex on facet # FIXME: Is it correct index in parallel? facet_vertex_0 = Vertex(cell.mesh(), f.entities(0)[0]) # Compute signed distance from vertex to facet plane d = (facet_vertex_0.point() - vertex.point()).dot(n) # Return norm of gradient assert d != 0.0, "Degenerate cell!" return 1.0/abs(d)
def myassemble(mesh): # Define basis functions and their gradients on the reference elements. def phi0(x): return 1.0 - x[0] - x[1] def phi1(x): return x[0] def phi2(x): return x[1] def f(x): return 1.0 phi = [phi0, phi1, phi2] dphi = np.array(([-1.0, -1.0], [1.0, 0.0], [0.0, 1.0])) # Define quadrature points midpoints = np.array(([0.5, 0.0], [0.5, 0.5], [0.0, 0.5])) N = mesh.num_vertices() A = np.zeros((N, N)) b = np.zeros((N, 1)) # Used to hold cell vertices coord = np.zeros([3, 2]) # Iterate over all cells, adding integral contribution to matrix/vector for c in cells(mesh): # Extract node numbers and vertex coordinates nodes = c.entities(0).astype('int') for i in range(0, 3): v = Vertex(mesh, int(nodes[i])) for j in range(0, 2): coord[i][j] = v.point()[j] # Compute Jacobian of map and area of cell J = np.outer(coord[0, :], dphi[0]) + \ np.outer(coord[1, :], dphi[1]) + \ np.outer(coord[2, :], dphi[2]) dx = 0.5 * abs(np.linalg.det(J)) # Iterate over quadrature points for p in midpoints: # Map p to physical cell x = coord[0, :] * phi[0](p) + \ coord[1, :] * phi[1](p) + \ coord[2, :] * phi[2](p) # Iterate over test functions for i in range(0, 3): v = phi[i](p) dv = np.linalg.solve(J.transpose(), dphi[i]) # Assemble vector (linear form) integral = f(x)*v*dx / 3.0 b[nodes[i]] += integral # Iterate over trial functions for j in range(0, 3): u = phi[j](p) du = np.linalg.solve(J.transpose(), dphi[j]) # Assemble matrix (bilinear form) integral = (np.inner(du, dv)) * dx / 3.0 integral += u * v * dx / 3.0 A[nodes[i], nodes[j]] += integral return A, b
def edge_to_vector(edge): v0, v1 = edge.entities(0) mesh = edge.mesh() v0 = Vertex(mesh, v0) v1 = Vertex(mesh, v1) return point_to_array(v1.point() - v0.point())