def compute_triangle_normal(self): self.t_normals=[] for face in df.faces(self.mesh): t=face.normal() #one must call normal() before entities(3),... cells = face.entities(3) if len(cells)==1: self.t_normals.append([t.x(),t.y(),t.z()]) self.t_normals=np.array(self.t_normals)
def compute_triangle_normal(self): self.face_nodes=[] self.face_norms=[] self.t_normals=[] for face in df.faces(self.mesh): t=face.normal() #one must call normal() before entities(3),... cells = face.entities(3) if len(cells)==1: face_nodes=face.entities(0) self.face_nodes.append(face_nodes) self.face_norms.append(t) self.t_normals.append([t.x(),t.y(),t.z()]) self.t_normals=np.array(self.t_normals) self.face_nodes_array=np.array(self.face_nodes,dtype=np.int32)
def test_convert_triangle(self): # Disabled because it fails, see FIXME below # test no. 1 from dolfin import Mesh, MPI if MPI.num_processes() != 1: return fname = os.path.join("data", "triangle") dfname = fname+".xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.triangle2xml(fname, dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) self.assertEqual(mesh.num_vertices(), 96) self.assertEqual(mesh.num_cells(), 159) # Clean up os.unlink(dfname) # test no. 2 from dolfin import MPI, Mesh, MeshFunction, \ edges, Edge, faces, Face, \ SubsetIterator, facets, CellFunction if MPI.num_processes() != 1: return fname = os.path.join("data", "test_Triangle_3") dfname = fname+".xml" dfname0 = fname+".attr0.xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.triangle2xml(fname, dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) mesh.init() mfun = MeshFunction('double', mesh, dfname0) self.assertEqual(mesh.num_vertices(), 58) self.assertEqual(mesh.num_cells(), 58) # Create a size_t CellFunction and assign the values based on the # converted Meshfunction cf = CellFunction("size_t", mesh) cf.array()[mfun.array()==10.0] = 0 cf.array()[mfun.array()==-10.0] = 1 # Meassure total area of cells with 1 and 2 marker add = lambda x, y : x+y area0 = reduce(add, (Face(mesh, cell.index()).area() \ for cell in SubsetIterator(cf, 0)), 0.0) area1 = reduce(add, (Face(mesh, cell.index()).area() \ for cell in SubsetIterator(cf, 1)), 0.0) total_area = reduce(add, (face.area() for face in faces(mesh)), 0.0) # Check that all cells in the two domains are either above or below y=0 self.assertTrue(all(cell.midpoint().y()<0 for cell in SubsetIterator(cf, 0))) self.assertTrue(all(cell.midpoint().y()>0 for cell in SubsetIterator(cf, 1))) # Check that the areas add up self.assertAlmostEqual(area0+area1, total_area) # Measure the edge length of the two edge domains edge_markers = mesh.domains().facet_domains() self.assertTrue(edge_markers is not None) length0 = reduce(add, (Edge(mesh, e.index()).length() \ for e in SubsetIterator(edge_markers, 0)), 0.0) length1 = reduce(add, (Edge(mesh, e.index()).length() \ for e in SubsetIterator(edge_markers, 1)), 0.0) # Total length of all edges and total length of boundary edges total_length = reduce(add, (e.length() for e in edges(mesh)), 0.0) boundary_length = reduce(add, (Edge(mesh, f.index()).length() \ for f in facets(mesh) if f.exterior()), 0.0) # Check that the edges add up self.assertAlmostEqual(length0+length1, total_length) self.assertAlmostEqual(length1, boundary_length) # Clean up os.unlink(dfname) os.unlink(dfname0)
def compute_affine_transformation_surface(self): m=self.m.vector().array() m=m.reshape((-1,3),order='F') cs=self.mesh.coordinates() self.face_nodes=[] self.face_norms=[] self.t_normals=[] for face in df.faces(self.mesh): t=face.normal() #one must call normal() before entities(3),... cells = face.entities(3) if len(cells)==1: face_nodes=face.entities(0) self.face_nodes.append(face_nodes) self.face_norms.append(t) self.t_normals.append([t.x(),t.y(),t.z()]) self.t_normals=np.array(self.t_normals) self.face_nodes_array=np.array(self.face_nodes,dtype=np.int32) self.s_nodes=[] self.s_weight=[] self.s_charge=[] def compute_det_xy(x1,y1,z1,x2,y2,z2,x3,y3,z3): a = y2*z1 - y3*z1 - y1*z2 + y3*z2 + y1*z3 - y2*z3 b = x2*z1 - x3*z1 - x1*z2 + x3*z2 + x1*z3 - x2*z3 c = x2*y1 - x3*y1 - x1*y2 + x3*y2 + x1*y3 - x2*y3 det=abs((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1)) det*=np.sqrt((a*a+b*b)/(c*c)+1) return det for i in range(len(self.face_nodes)): f_c=self.face_nodes[i] x1,y1,z1=cs[f_c[0]] x2,y2,z2=cs[f_c[1]] x3,y3,z3=cs[f_c[2]] c11=x2-x1 c12=x3-x1 c21=y2-y1 c22=y3-y1 c31=z2-z1 c32=z3-z1 t=self.face_norms[i] if abs(t.z())>abs(t.x()) and abs(t.z())>abs(t.y()): det=compute_det_xy(x1,y1,z1,x2,y2,z2,x3,y3,z3) elif abs(t.y())>abs(t.x()): det=compute_det_xy(z1,x1,y1,z2,x2,y2,z3,x3,y3) else: det=compute_det_xy(y1,z1,x1,y2,z2,x2,y3,z3,x3) sa=(m[f_c[0]][0]*t.x()+m[f_c[0]][1]*t.y()+m[f_c[0]][2]*t.z()) sb=(m[f_c[1]][0]*t.x()+m[f_c[1]][1]*t.y()+m[f_c[1]][2]*t.z()) sc=(m[f_c[2]][0]*t.x()+m[f_c[2]][1]*t.y()+m[f_c[2]][2]*t.z()) for j in range(len(self.s_x)): x=c11*self.s_x[j]+c12*self.s_y[j]+x1 y=c21*self.s_x[j]+c22*self.s_y[j]+y1 z=c31*self.s_x[j]+c32*self.s_y[j]+z1 self.s_nodes.append([x,y,z]) self.s_weight.append(det*self.s_w[j]) self.s_charge.append(sa+(sb-sa)*self.s_x[j]+(sc-sa)*self.s_y[j])
def assemble_3d(mesh): v0, v1, v2, v3, divs = compute_nodal_tetrahedron() cs = mesh.coordinates() BDM = df.FunctionSpace(mesh, "BDM", 1) fun = df.Function(BDM) n = fun.vector().size() mat = sp.lil_matrix((n, n)) m = mesh.num_cells() mat_K = sp.lil_matrix((n, m)) map = BDM.dofmap() for cell in df.cells(mesh): ci = cell.entities(0) cm = [] cm.append(cs[ci[1]] - cs[ci[0]]) cm.append(cs[ci[2]] - cs[ci[0]]) cm.append(cs[ci[3]] - cs[ci[0]]) A = np.transpose(np.array(cm)) B = np.dot(np.transpose(A), A) J = np.linalg.det(A) K = B / abs(J) cfs = map.cell_dofs(cell.index()) for i in range(12): for j in range(12): tmp = mat[cfs[i], cfs[j]] tmp_res = np.dot(np.dot(K,v0[i]),v0[j]) \ + np.dot(np.dot(K,v1[i]),v1[j]) \ + np.dot(np.dot(K,v2[i]),v2[j]) \ + np.dot(np.dot(K,v3[i]),v3[j]) mat[cfs[i], cfs[j]] = tmp + tmp_res / 24.0 id_c = cell.index() for j in range(12): tmp = mat_K[cfs[j], id_c] if J > 0: mat_K[cfs[j], id_c] = tmp + divs[j] else: mat_K[cfs[j], id_c] = tmp - divs[j] idy = generate_nonzero_ids(mat) mesh.init(2, 3) for face in df.faces(mesh): cells = face.entities(3) if len(cells) == 1: c = df.Cell(mesh, cells[0]) cfs = map.cell_dofs(c.index()) ids = map.tabulate_facet_dofs(c.index(face)) zid = cfs[ids] for i in zid: mat[i, idy[i]] = 0 mat[idy[i], i] = 0 mat[i, i] = 1 import time t1 = time.time() A_inv = sparse_inverse(mat.tocsc()) #t2=time.time() #print 't2-t1 (s)',t2-t1 #A_inv = spl.inv(mat.tocsc()) #t3=time.time() #print 't3-t2 (s)',t3-t2 K3 = A_inv * mat_K.tocsr() K3 = K3.tolil() idy = generate_nonzero_ids(K3) mesh.init(2, 3) for face in df.faces(mesh): cells = face.entities(3) if len(cells) == 1: c = df.Cell(mesh, cells[0]) cfs = map.cell_dofs(c.index()) ids = map.tabulate_facet_dofs(c.index(face)) for i in cfs[ids]: K3[i, idy[i]] = 0 K1 = mat_K.transpose() K = K1 * K3.tocsr() DG = df.FunctionSpace(mesh, "DG", 0) v = df.TestFunction(DG) L = df.assemble(v * df.dx).array() return K, L
def test_convert_triangle( self): # Disabled because it fails, see FIXME below # test no. 1 from dolfin import Mesh, MPI fname = os.path.join(os.path.dirname(__file__), "data", "triangle") dfname = fname + ".xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.triangle2xml(fname, dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) self.assertEqual(mesh.num_vertices(), 96) self.assertEqual(mesh.num_cells(), 159) # Clean up os.unlink(dfname) # test no. 2 from dolfin import MPI, Mesh, MeshFunction, \ edges, Edge, faces, Face, \ SubsetIterator, facets fname = os.path.join(os.path.dirname(__file__), "data", "test_Triangle_3") dfname = fname + ".xml" dfname0 = fname + ".attr0.xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.triangle2xml(fname, dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) mesh.init() mfun = MeshFunction('double', mesh, dfname0) self.assertEqual(mesh.num_vertices(), 58) self.assertEqual(mesh.num_cells(), 58) # Create a size_t MeshFunction and assign the values based on the # converted Meshfunction cf = MeshFunction("size_t", mesh, mesh.topology().dim()) cf.array()[mfun.array() == 10.0] = 0 cf.array()[mfun.array() == -10.0] = 1 # Meassure total area of cells with 1 and 2 marker add = lambda x, y: x + y area0 = reduce(add, (Face(mesh, cell.index()).area() \ for cell in SubsetIterator(cf, 0)), 0.0) area1 = reduce(add, (Face(mesh, cell.index()).area() \ for cell in SubsetIterator(cf, 1)), 0.0) total_area = reduce(add, (face.area() for face in faces(mesh)), 0.0) # Check that all cells in the two domains are either above or below y=0 self.assertTrue( all(cell.midpoint().y() < 0 for cell in SubsetIterator(cf, 0))) self.assertTrue( all(cell.midpoint().y() > 0 for cell in SubsetIterator(cf, 1))) # Check that the areas add up self.assertAlmostEqual(area0 + area1, total_area) # Measure the edge length of the two edge domains #edge_markers = mesh.domains().facet_domains() edge_markers = mesh.domains().markers(mesh.topology().dim() - 1) self.assertTrue(edge_markers is not None) #length0 = reduce(add, (Edge(mesh, e.index()).length() \ # for e in SubsetIterator(edge_markers, 0)), 0.0) length0, length1 = 0.0, 0.0 for item in list(edge_markers.items()): if item[1] == 0: e = Edge(mesh, int(item[0])) length0 += Edge(mesh, int(item[0])).length() elif item[1] == 1: length1 += Edge(mesh, int(item[0])).length() # Total length of all edges and total length of boundary edges total_length = reduce(add, (e.length() for e in edges(mesh)), 0.0) boundary_length = reduce(add, (Edge(mesh, f.index()).length() \ for f in facets(mesh) if f.exterior()), 0.0) # Check that the edges add up self.assertAlmostEqual(length0 + length1, total_length) self.assertAlmostEqual(length1, boundary_length) # Clean up os.unlink(dfname) os.unlink(dfname0)