def setupMeshes(cls, mesh, N, num_refine=0, randref=(1.0, 1.0)): """Create a set of N meshes based on provided mesh. Parameters num_refine>=0 and randref specify refinement adjustments. num_refine specifies the number of refinements per mesh, randref[0] specifies the probability that a given mesh is refined, and randref[1] specifies the probability that an element of the mesh is refined (if it is refined at all). """ assert num_refine >= 0 assert 0 < randref[0] <= 1.0 assert 0 < randref[1] <= 1.0 # create set of (refined) meshes meshes = list(); for _ in range(N): m = Mesh(mesh) for _ in range(num_refine): if randref[0] == 1.0 and randref[1] == 1.0: m = refine(m) elif random() <= randref[0]: cell_markers = CellFunction("bool", m) cell_markers.set_all(False) cell_ids = range(m.num_cells()) shuffle(cell_ids) num_ref_cells = int(ceil(m.num_cells() * randref[1])) for cell_id in cell_ids[0:num_ref_cells]: cell_markers[cell_id] = True m = refine(m, cell_markers) meshes.append(m) return meshes
def test_convert_diffpack(self): from dolfin import Mesh, MPI, MeshFunction if MPI.num_processes() != 1: return fname = os.path.join("data", "diffpack_tet") dfname = fname+".xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.diffpack2xml(fname+".grid", dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) self.assertEqual(mesh.num_vertices(), 27) self.assertEqual(mesh.num_cells(), 48) self.assertEqual(mesh.domains().markers(3).size(), 48) self.assertEqual(mesh.domains().markers(2).size(), 16) mf_basename = dfname.replace(".xml", "_marker_%d.xml") for marker, num in [(3, 9), (6, 9), (7, 3), (8, 1)]: mf_name = mf_basename % marker mf = MeshFunction("uint", mesh, mf_name) self.assertEqual(sum(mf.array()==marker), num) os.unlink(mf_name) # Clean up os.unlink(dfname)
def vtk_ug_to_dolfin_mesh(ug): """ Create a DOLFIN Mesh from a vtkUnstructuredGrid object """ if not isinstance(ug, vtk.vtkUnstructuredGrid): raise TypeError("Expected a 'vtkUnstructuredGrid'") # Get mesh data num_cells = int(ug.GetNumberOfCells()) num_vertices = int(ug.GetNumberOfPoints()) # Get topological and geometrical dimensions cell = ug.GetCell(0) gdim = int(cell.GetCellDimension()) cell_type = cell.GetCellType() if cell_type not in [vtk.VTK_TETRA, vtk.VTK_TRIANGLE]: raise TypeError("DOLFIN only support meshes of triangles " + \ "and tetrahedrons.") tdim = 3 if cell_type == vtk.VTK_TETRA else 2 # Create empty DOLFIN Mesh mesh = Mesh() editor = MeshEditor() editor.open(mesh, tdim, gdim) editor.init_cells(num_cells) editor.init_vertices(num_vertices) editor.close() # Assign the cell and vertex informations directly from the vtk data cells_array = array_handler.vtk2array(ug.GetCells().GetData()) # Get the assumed fixed size of indices and create an index array cell_size = cell.GetPointIds().GetNumberOfIds() cellinds = np.arange(len(cells_array)) # Each cell_ids_size:th data point need to be deleted from the # index array ind_delete = slice(0, len(cells_array), cell_size+1) # Check that the removed value all have the same value which should # be the size of the data if not np.all(cells_array[ind_delete]==cell_size): raise ValueError("Expected all cells to be of the same size") cellinds = np.delete(cellinds, ind_delete) # Get cell data from mesh and make it writeable (cell data is non # writeable by default) and update the values mesh_cells = mesh.cells() mesh_cells.flags.writeable = True mesh_cells[:] = np.reshape(cells_array[cellinds], \ (num_cells , cell_size)) # Set coordinates from vtk data vertex_array = array_handler.vtk2array(ug.GetPoints().GetData()) if vertex_array.shape[1] != gdim: vertex_array = vertex_array[:,:gdim] mesh.coordinates()[:] = vertex_array return mesh
def test_convert_diffpack_2d(self): from dolfin import Mesh, MPI, MeshFunction, mpi_comm_world fname = os.path.join(os.path.dirname(__file__), "data", "diffpack_tri") dfname = fname+".xml" # Read triangle file and convert to a dolfin xml mesh file meshconvert.diffpack2xml(fname+".grid", dfname) # Read in dolfin mesh and check number of cells and vertices mesh = Mesh(dfname) self.assertEqual(mesh.num_vertices(), 41) self.assertEqual(mesh.num_cells(), 64) self.assertEqual(len(mesh.domains().markers(2)), 64) mf_basename = dfname.replace(".xml", "_marker_%d.xml") for marker, num in [(1,10), (2,5), (3,5)]: mf_name = mf_basename % marker mf = MeshFunction("size_t", mesh, mf_name) self.assertEqual(sum(mf.array()==marker), num) os.unlink(mf_name) # Clean up os.unlink(dfname)
def make_mesh(coordinates, cells, tdim, gdim, mesh=None): '''Mesh by MeshEditor from vertices and cells''' if mesh is None: mesh = Mesh() assert mesh.mpi_comm().size == 1 module.fill_mesh(coordinates.flatten(), cells.flatten(), tdim, gdim, mesh) return mesh
def readmesh(mesh_file): ''' read HDF5 or DOLFIN XML mesh ''' # TODO: exceptions, files exist? from dolfin import Mesh, MeshFunction, CellFunction, HDF5File, \ FacetFunction tmp = mesh_file.split('/')[-1].split('.') mesh_type = tmp[-1] mesh_name = '.'.join(tmp[0:-1]) if mesh_type == 'xml': mesh = Mesh(mesh_file) rank = mesh.mpi_comm().Get_rank() try: subdomains = MeshFunction("size_t", mesh, mesh_name+"_physical_region.xml") except: if rank == 0: print('no subdomain file found (%s)' % (mesh_name+"_physical_region.xml")) subdomains = CellFunction("size_t", mesh) try: boundaries = MeshFunction("size_t", mesh, mesh_name+"_facet_region.xml") except: if rank == 0: print('no boundary file found (%s)' % (mesh_name+"_physical_region.xml")) boundaries = FacetFunction("size_t", mesh) elif mesh_type == 'h5': mesh = Mesh() rank = mesh.mpi_comm().Get_rank() hdf = HDF5File(mesh.mpi_comm(), mesh_file, "r") hdf.read(mesh, "/mesh", False) subdomains = CellFunction("size_t", mesh) boundaries = FacetFunction("size_t", mesh) if hdf.has_dataset('subdomains'): hdf.read(subdomains, "/subdomains") else: if rank == 0: print('no <subdomains> datasets found in file %s' % mesh_file) if hdf.has_dataset('boundaries'): hdf.read(boundaries, "/boundaries") else: if rank == 0: print('no <boundaries> datasets found in file %s' % mesh_file) elif mesh_type in ['xdmf', 'xmf']: import sys sys.exit('XDMF not supported yet. Use HDF5 instead!') else: import sys sys.exit('mesh format not recognized. try XML (serial) or HDF5') # NOTE http://fenicsproject.org/qa/5337/importing-marked-mesh-for-parallel-use # see file xml2xdmf.py return mesh, subdomains, boundaries
def cyclic3D(u): """ Symmetrize with respect to (xyz) cycle. """ try: nrm = np.linalg.norm(u.vector()) V = u.function_space() assert V.mesh().topology().dim() == 3 mesh1 = Mesh(V.mesh()) mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]] W1 = FunctionSpace(mesh1, 'CG', 1) # testing if symmetric bc = DirichletBC(V, 1, DomainBoundary()) test = Function(V) bc.apply(test.vector()) test = interpolate(Function(W1, test.vector()), V) assert max(test.vector()) - min(test.vector()) < 1.1 v1 = interpolate(Function(W1, u.vector()), V) mesh2 = Mesh(mesh1) mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]] W2 = FunctionSpace(mesh2, 'CG', 1) v2 = interpolate(Function(W2, u.vector()), V) pr = project(u+v1+v2) assert np.linalg.norm(pr.vector())/nrm > 0.01 return pr except: print "Cyclic symmetrization failed!" return u
def polyhedron_mesh(data): """ Build polyhedral mesh. Must be strlike with respect to the origin. Input: data[0] - list of vertices data[1] - list of faces data[2] - optional other starlike point, instead of the origin """ # TODO: Center of mass of the vertices as origin vertex_data = np.array(data[0], dtype='double') lowest = np.min(flatten(data[1])) face_data = [list(np.array(d) - lowest) for d in data[1]] numv = len(vertex_data) # will be the index of the origin if len(data) > 2: origin = np.array(data[2], dtype='double') else: origin = [0.0, 0.0, 0.0] mesh = Mesh() editor = DynamicMeshEditor() editor.open(mesh, "tetrahedron", 3, 3, numv + 1, len(face_data)) for i, vert in enumerate(vertex_data): editor.add_vertex(i, *vert) editor.add_vertex(numv, *origin) newv = numv + 1 # next vertex index newf = 0 # next face index for face in face_data: if len(face) == 3: # triangular face, no splitting editor.add_cell(newf, numv, *face) # face + origin newf += 1 else: # split face into triangles using center of mass # average face vertices to get the center vert = list(np.mean(vertex_data[np.array(face)], axis=0)) editor.add_vertex(newv, *vert) # new vertex: face center face.append(face[0]) for i in zip(face[:-1], face[1:]): # pairs of vertices editor.add_cell(newf, numv, newv, *i) # + face center + origin newf += 1 newv += 1 editor.close() mesh.order() return mesh
def convert_and_create_facet_mesh_function ( ifilename, ofilename ): # First convert the gmsh mesh meshconvert.convert2xml ( ifilename, ofilename ) # Now load the created mesh and initialise the required connectivity information mesh = Mesh ( ofilename ) mesh.order() File ( ofilename ) << mesh D = mesh.topology().dim() mesh.init(D-1, 0) # read the data from the gmsh file once again dim_count, vertices_used, tags = process_gmsh_elements( ifilename, D-1 ) # Get the facet-node connectivity information (reshape as a row of node indices per facet) facets_as_nodes = mesh.topology()(D-1,0)().reshape ( mesh.num_facets(), D ) # Create and initialise the mesh function facet_mark_function = MeshFunction ( 'uint', mesh, D-1 ) facet_mark_function.set_all( 0 ) # set the relevant values of the mesh function facets_to_check = range( mesh.num_facets() ) for i in range(len(tags)): nodes = np.sort(np.array(vertices_used[2*i:(2*i+D)])) value = tags[i][0] if value != 0: found = False for j in range(len(facets_to_check)): index = facets_to_check[j] if np.array_equal(facets_as_nodes[index,:], nodes): found = True; facets_to_check.pop(j) # set the value of the mesh function facet_mark_function[index] = value break; if not found: raise Exception ( "The facet (%d) was not found to mark: %s" % (i, nodes) ) # save the mesh function to file fname = os.path.splitext(ofilename)[0] mesh_function_file = File("%s_%s.xml" % (fname, "facet_regions")) mesh_function_file << facet_mark_function
def write_fenics_file(dim, ofilename): ofile = File(ofilename + '.xml') mesh = Mesh() editor = MeshEditor() editor.open(mesh, dim, dim) editor.init_vertices(nodes.shape[1]) editor.init_cells(len(cell_map)) for i in range(nodes.shape[1]): if dim == 2: editor.add_vertex(i, nodes[0, i], nodes[1, i]) else: editor.add_vertex(i, nodes[0, i], nodes[1, i], nodes[2, i]) for i in range(1, len(cell_map)+1): if dim == 2: editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1) else: editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1, cell_map[i][3]-1) mesh.order() mvc = mesh.domains().markers(dim-1) for zone, cells in boundary_cells.iteritems(): for cell, nds in cells.iteritems(): dolfin_cell = Cell(mesh, cell-1) nodes_of_cell = dolfin_cell.entities(0) #print cell #print nodes_of_cell nodes_of_face = nds - 1 #print nodes_of_face for jj, ff in enumerate(facets(dolfin_cell)): facet_nodes = ff.entities(0) #print facet_nodes if all(map(lambda x: x in nodes_of_face, facet_nodes)): local_index = jj break mvc.set_value(cell-1, local_index, zone) ofile << mesh from dolfin import plot plot(mesh, interactive=True) print 'Finished writing FEniCS mesh\n'
def rotational(u, n): """ Symmetrize with respect to n-fold symmetry. """ # TODO: test one rotation only V = u.function_space() if V.mesh().topology().dim() > 2 or n < 2: return u mesh = V.mesh() sum = u nrm = np.linalg.norm(u.vector()) rotation = np.array([[np.cos(2*np.pi/n), np.sin(2*np.pi/n)], [-np.sin(2*np.pi/n), np.cos(2*np.pi/n)]]) for i in range(1, n): mesh = Mesh(mesh) mesh.coordinates()[:, :] = np.dot(mesh.coordinates(), rotation) W = FunctionSpace(mesh, 'CG', 1) v = interpolate(Function(W, u.vector()), V) sum += v pr = project(sum) if np.linalg.norm(pr.vector())/nrm > 0.01: return pr else: return u
def get(self): """Two cells.""" topx, topy = self.pad(self.values) mesh = Mesh() editor = MeshEditor() editor.open(mesh, 2, 2) editor.init_vertices(4) editor.init_cells(2) editor.add_vertex(0, 0, 0) editor.add_vertex(1, 1, 0) editor.add_vertex(2, topx, topy) editor.add_vertex(3, 1 - topx, -topy) editor.add_cell(0, 0, 1, 2) editor.add_cell(1, 0, 1, 3) editor.close() return mesh
def test_manifold_point_search(): # Simple two-triangle surface in 3d vertices = [(0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0)] cells = [(0, 1, 2), (0, 1, 3)] mesh = Mesh(MPI.comm_world, CellType.Type.triangle, numpy.array(vertices, dtype=numpy.float64), numpy.array(cells, dtype=numpy.int32), [], cpp.mesh.GhostMode.none) bb = BoundingBoxTree(mesh, mesh.topology.dim) p = Point(0.5, 0.25, 0.75) assert bb.compute_first_entity_collision(p, mesh) == 0 p = Point(0.25, 0.5, 0.75) assert bb.compute_first_entity_collision(p, mesh) == 1
def symmetrize(u, d, sym): """ Symmetrize function u. """ if len(d) == 3: # three dimensions -> cycle XYZ return cyclic3D(u) elif len(d) >= 4: # four dimensions -> rotations in 2D return rotational(u, d[-1]) nrm = np.linalg.norm(u.vector()) V = u.function_space() mesh = Mesh(V.mesh()) # test if domain is symmetric using function equal 0 inside, 1 on boundary # extrapolation will force large values if not symmetric since the flipped # domain is different bc = DirichletBC(V, 1, DomainBoundary()) test = Function(V) bc.apply(test.vector()) if len(d) == 2: # two dimensions given: swap dimensions mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]] else: # one dimension given: reflect mesh.coordinates()[:, d[0]] *= -1 # FIXME functionspace takes a long time to construct, maybe copy? W = FunctionSpace(mesh, 'CG', 1) try: # testing test = interpolate(Function(W, test.vector()), V) # max-min should be around 1 if domain was symmetric # may be slightly above due to boundary approximation assert max(test.vector()) - min(test.vector()) < 1.1 v = interpolate(Function(W, u.vector()), V) if sym: # symmetric pr = project(u + v) else: # antisymmetric pr = project(u - v) # small solution norm most likely means that symmetrization gives # trivial function assert np.linalg.norm(pr.vector()) / nrm > 0.01 return pr except: # symmetrization failed for some reason print "Symmetrization " + str(d) + " failed!" return u
def build_mesh_old(cells, vertices): """Assemble a mesh object from cells and vertices.""" mesh = Mesh() editor = MeshEditor() dim = len(vertices[0]) if dim == 2: editor.open(mesh, 'triangle', 2, 2) else: editor.open(mesh, 'tetrahedron', 3, 3) editor.init_vertices(len(vertices)) editor.init_cells(len(cells)) for i, v in enumerate(vertices): editor.add_vertex(i, *v) for i, c in enumerate(cells): editor.add_cell(i, *c) editor.close() return mesh
def create_mesh(lcar): x0 = 0.0 x1 = 0.1 y0 = 0.0 y1 = 0.2 mesh_eps = 1.0e-12 # pylint: disable=no-self-use class HotBoundary(SubDomain): def inside(self, x, on_boundary): return (on_boundary and x0 + mesh_eps < x[0] < x1 - mesh_eps and y0 + mesh_eps < x[1] < y1 - mesh_eps) hot_boundary = HotBoundary() class CoolBoundary(SubDomain): def inside(self, x, on_boundary): return (on_boundary and (x[0] < x0 + mesh_eps or x[0] > x1 - mesh_eps or x[1] < y0 + mesh_eps or x[1] > y1 - mesh_eps)) cool_boundary = CoolBoundary() cache_file = 'boussinesq-{}.msh'.format(lcar) if os.path.isfile(cache_file): print('Using mesh from cache \'{}\'.'.format(cache_file)) points, cells, _, _, _ = meshio.read(cache_file) else: geom = pygmsh.Geometry() circle = geom.add_circle([0.05, 0.05, 0.0], 0.02, lcar, make_surface=False) geom.add_rectangle(x0, x1, y0, y1, 0.0, lcar, holes=[circle]) points, cells, _, _, _ = pygmsh.generate_mesh(geom) meshio.write(cache_file, points, cells) # https://fenicsproject.org/qa/12891/initialize-mesh-from-vertices-connectivities-at-once meshio.write('test.xml', points, cells) return Mesh('test.xml'), hot_boundary, cool_boundary
def get(self): """Part of the regular polygon construction.""" sides, angle = self.pad(self.values) mesh = Mesh() editor = MeshEditor() editor.open(mesh, 2, 2) # dimension editor.init_vertices(angle + 2) editor.init_cells(angle) editor.add_vertex(0, 0, 0) for i in range(0, angle + 1): editor.add_vertex(i + 1, cos(2 * pi * i / sides), sin(2 * pi * i / sides)) editor.add_cell(0, 2, 1, 0) for i in range(1, angle): editor.add_cell(i, 0, i + 1, i + 2) editor.close() return mesh
def get(self): """One triangle per side with common vertex at (0,0).""" sides = self.values[0] mesh = Mesh() editor = MeshEditor() editor.open(mesh, 2, 2) editor.init_vertices(sides + 1) editor.init_cells(sides) editor.add_vertex(0, 0, 0) for i in range(1, sides + 1): editor.add_vertex(i, cos(2 * pi * i / sides), sin(2 * pi * i / sides)) for i in range(sides - 1): editor.add_cell(i, 0, i + 1, i + 2) editor.add_cell(sides - 1, 0, sides, 1) editor.close() return mesh
def plot(args): from dolfin import plot, interactive, Mesh, Function, VectorFunctionSpace # Plot the mesh mesh = Mesh(args.xml) plot(mesh, title="Mesh") interactive() # Plot velocities if args.velocity is not None: G = VectorFunctionSpace(mesh, "DG", 0) base_file = args.velocity[:-4] + "_{}.xml" for i, u in enumerate(fvcom_reader.velocity): g = Function(G, base_file.format(i)) plot(g, title="Velocity time={}".format(i)) interactive()
def import_mesh_from_xdmf(domain="domain.xdmf", boundaries="boundaries.xdmf", labels="labels.yaml", subdomains=False, dim=2, directory="."): """ Function importing a msh mesh and converting it into a dolfin mesh. Arguments: - domain (str): name of the domain XDMF file; - boundaries (str): name of the boundaries XDMF file; - dim (int): dimension of the domain; - subdomains (bool): true if there are subdomains, else false - directory (str): (optional) directory of the mesh; Output: - dolfin Mesh object containing the domain; - dolfin MeshFunction object containing the physical lines (dim=2) or surfaces (dim=3) defined in the msh file and the sub-domains; - a dictionary with labels for boundaries and subdomains """ # Import the converted domain mesh = Mesh() with XDMFFile("{}/{}".format(directory, domain)) as infile: infile.read(mesh) # Import the boundaries boundaries_mvc = MeshValueCollection("size_t", mesh, dim=dim) with XDMFFile("{}/{}".format(directory, boundaries)) as infile: infile.read(boundaries_mvc, 'boundaries') boundaries_mf = MeshFunctionSizet(mesh, boundaries_mvc) # Import the subdomains if subdomains: subdomains_mvc = MeshValueCollection("size_t", mesh, dim=dim) with XDMFFile("{}/{}".format(directory, domain)) as infile: infile.read(subdomains_mvc, 'subdomains') subdomains_mf = MeshFunctionSizet(mesh, subdomains_mvc) # Import labels with open("{}/{}".format(directory, labels), 'r') as infile: labels = yaml.load(infile, Loader=yaml.FullLoader) # Return the Mesh and the MeshFunction objects if not subdomains: return mesh, boundaries_mf, labels else: return mesh, boundaries_mf, subdomains_mf, labels print(labels)
def get(self): """Build cells based on triangulated regular polygon.""" sides, h, x, y = self.pad(self.values) mesh = Mesh() editor = MeshEditor() editor.open(mesh, 3, 3) # dimension editor.init_vertices(sides + 2) editor.init_cells(sides) editor.add_vertex(0, x, y, h) for i in range(1, sides + 1): editor.add_vertex(i, cos(2 * pi * i / sides), sin(2 * pi * i / sides), 0) editor.add_vertex(sides + 1, 0, 0, 0) for i in range(sides - 1): editor.add_cell(i, 0, i + 1, i + 2, sides + 1) editor.add_cell(sides - 1, 0, sides, 1, sides + 1) editor.close() return mesh
def get_reference_element(dim=2): nodes, cell = get_reference_coordinates(dim) cells = np.atleast_2d(np.arange( dim + 1, dtype=np.uintp)) # connection of nodes (defines element) # this piece of code creates a mesh containing one element only mesh = Mesh() editor = MeshEditor() editor.open(mesh, cell, dim, dim) editor.init_vertices(dim + 1) editor.init_cells(1) for i, n in enumerate(nodes): p = Point(n) editor.add_vertex(i, p) for i, n in enumerate(cells): editor.add_cell(i, n) editor.close() return mesh
def project_gradients( mesh: df.Mesh, scalar_solutions: Dict[str, df.Function], fiber_space: str = "CG_1", ) -> Dict[str, np.ndarray]: """ Calculate the gradients using projections Arguments --------- mesh : dolfin.Mesh The mesh fiber_space : str A string on the form {familiy}_{degree} which determines for what space the fibers should be calculated for. scalar_solutions: dict A dictionary with the scalar solutions that you want to compute the gradients of. """ Vv = utils.space_from_string(fiber_space, mesh, dim=3) V = utils.space_from_string(fiber_space, mesh, dim=1) data = {} V_cg = df.FunctionSpace(mesh, df.VectorElement("Lagrange", mesh.ufl_cell(), 1)) for case, scalar_solution in scalar_solutions.items(): scalar_solution_int = df.interpolate(scalar_solution, V) if case != "lv_rv": gradient_cg = df.project(df.grad(scalar_solution), V_cg, solver_type="cg") gradient = df.interpolate(gradient_cg, Vv) # Add gradient data data[case + "_gradient"] = gradient.vector().get_local() # Add scalar data if case != "apex": data[case + "_scalar"] = scalar_solution_int.vector().get_local() # Return data return data
def load_h5_mesh(h5_file, scale_factor=None): '''Unpack to mesh, volumes and surfaces''' mesh = Mesh() h5 = HDF5File(mesh.mpi_comm(), h5_file, 'r') h5.read(mesh, 'mesh', False) # Convert units if scale_factor is not None: assert scale_factor > 0, "Scale factor must be a positive real number!" mesh.coordinates()[:] *= scale_factor surfaces = MeshFunction('size_t', mesh, mesh.topology().dim() - 1) h5.read(surfaces, 'surfaces') volumes = MeshFunction('size_t', mesh, mesh.topology().dim()) h5.read(volumes, 'volumes') return mesh, volumes, surfaces
def test_store_mesh(casedir): pp = PostProcessor(dict(casedir=casedir)) from dolfin import (UnitSquareMesh, CellFunction, FacetFunction, AutoSubDomain, Mesh, HDF5File, assemble, Expression, ds, dx) # Store mesh mesh = UnitSquareMesh(6, 6) celldomains = CellFunction("size_t", mesh) celldomains.set_all(0) AutoSubDomain(lambda x: x[0] < 0.5).mark(celldomains, 1) facetdomains = FacetFunction("size_t", mesh) AutoSubDomain(lambda x, on_boundary: x[0] < 0.5 and on_boundary).mark( facetdomains, 1) pp.store_mesh(mesh, celldomains, facetdomains) # Read mesh back mesh2 = Mesh() f = HDF5File(mpi_comm_world(), os.path.join(pp.get_casedir(), "mesh.hdf5"), 'r') f.read(mesh2, "Mesh", False) celldomains2 = CellFunction("size_t", mesh2) f.read(celldomains2, "CellDomains") facetdomains2 = FacetFunction("size_t", mesh2) f.read(facetdomains2, "FacetDomains") e = Expression("1+x[1]", degree=1) dx1 = dx(1, domain=mesh, subdomain_data=celldomains) dx2 = dx(1, domain=mesh2, subdomain_data=celldomains2) C1 = assemble(e * dx1) C2 = assemble(e * dx2) assert abs(C1 - C2) < 1e-10 ds1 = ds(1, domain=mesh, subdomain_data=facetdomains) ds2 = ds(1, domain=mesh2, subdomain_data=facetdomains2) F1 = assemble(e * ds1) F2 = assemble(e * ds2) assert abs(F1 - F2) < 1e-10
def build_interval_mesh(vertices, cells): '''Mesh of 1d topology in n-dims.''' imesh = Mesh() editor = MeshEditor() editor.open(imesh, 1, vertices.shape[1]) editor.init_vertices(len(vertices)) editor.init_cells(len(cells)) # Add vertices for vertex_index, v in enumerate(vertices): editor.add_vertex(vertex_index, v) # Add cells for cell_index, (v0, v1) in enumerate(cells): editor.add_cell(cell_index, v0, v1) editor.close() return imesh
def get(self): """ Unzip and convert to xml if possible.""" mesh = output = None import tempfile import os if not os.path.isfile(self.params): return None params = self.params try: split = os.path.splitext(params) if split[-1] == '.gz': # unzip the mesh import gzip f = gzip.open(params, 'rb') content = f.read() f.close() input = tempfile.NamedTemporaryFile(suffix=os.path.splitext( split[0])[-1], delete=False) input.write(content) input.close() params = input.name split = os.path.splitext(params) if split[-1] != '.xml': # convert using dolfin's meshconvert from dolfin_utils.meshconvert import meshconvert output = tempfile.NamedTemporaryFile(suffix='.xml', delete=False) output.close() meshconvert.convert2xml(params, output.name) params = output.name # use Mesh constructor with filename mesh = Mesh(params) try: os.unlink(output.name) except OSError: pass os.unlink(input.name) # many things could go wrong here # just return None as mesh if mesh importing failed finally: return mesh
def setUp(self, *args, **kwargs): self.mesh = Mesh() editor = MeshEditor() editor.open(self.mesh, 2, 2) # topo_dim = 2, geom dim = 2 editor.init_vertices(6) editor.init_cells(2) vertex_0 = Vertex(self.mesh, 0) vertex_1 = Vertex(self.mesh, 1) vertex_2 = Vertex(self.mesh, 2) vertex_3 = Vertex(self.mesh, 3) vertex_4 = Vertex(self.mesh, 4) vertex_5 = Vertex(self.mesh, 5) editor.add_cell(0,1,2,3) editor.add_cell(1,0,2,3) editor.close()
def symmetrize(u, d, sym): """ Symmetrize function u. """ if len(d) == 3: # three dimensions -> cycle XYZ return cyclic3D(u) elif len(d) >= 4: # four dimensions -> rotations in 2D return rotational(u, d[-1]) nrm = np.linalg.norm(u.vector()) V = u.function_space() mesh = Mesh(V.mesh()) # test if domain is symmetric using function equal 0 inside, 1 on boundary # extrapolation will force large values if not symmetric since the flipped # domain is different bc = DirichletBC(V, 1, DomainBoundary()) test = Function(V) bc.apply(test.vector()) if len(d) == 2: # two dimensions given: swap dimensions mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]] else: # one dimension given: reflect mesh.coordinates()[:, d[0]] *= -1 # FIXME functionspace takes a long time to construct, maybe copy? W = FunctionSpace(mesh, 'CG', 1) try: # testing test = interpolate(Function(W, test.vector()), V) # max-min should be around 1 if domain was symmetric # may be slightly above due to boundary approximation assert max(test.vector()) - min(test.vector()) < 1.1 v = interpolate(Function(W, u.vector()), V) if sym: # symmetric pr = project(u+v) else: # antisymmetric pr = project(u-v) # small solution norm most likely means that symmetrization gives # trivial function assert np.linalg.norm(pr.vector())/nrm > 0.01 return pr except: # symmetrization failed for some reason print "Symmetrization " + str(d) + " failed!" return u
def test_readme_images(): from dolfin import ( MeshEditor, Mesh, FunctionSpace, assemble, EigenMatrix, dot, grad, dx, TrialFunction, TestFunction ) import meshzoo points, cells = meshzoo.rectangle(-1.0, 1.0, -1.0, 1.0, 20, 20) # Convert points, cells to dolfin mesh editor = MeshEditor() mesh = Mesh() # topological and geometrical dimension 2 editor.open(mesh, 'triangle', 2, 2, 1) editor.init_vertices(len(points)) editor.init_cells(len(cells)) for k, point in enumerate(points): editor.add_vertex(k, point[:2]) for k, cell in enumerate(cells.astype(numpy.uintp)): editor.add_cell(k, cell) editor.close() V = FunctionSpace(mesh, 'CG', 1) u = TrialFunction(V) v = TestFunction(V) L = EigenMatrix() assemble(dot(grad(u), grad(v)) * dx, tensor=L) A = L.sparray() # M = A.T.dot(A) M = A with tempfile.TemporaryDirectory() as temp_dir: filepath = os.path.join(temp_dir, 'test.png') betterspy.write_png(filepath, M, border_width=2) # betterspy.write_png( # 'ATA.png', M, border_width=2, # colormap='viridis' # ) return
def pons(): base = "../meshes/2d/pons" mesh = Mesh(base + ".xml") subdomains = MeshFunction("size_t", mesh, base + "_physical_region.xml") subdomain_materials = {19: "graphite", 20: "SiC", 21: "air"} for k in range(1, 19, 2): subdomain_materials[k] = "air" for k in range(2, 19, 2): subdomain_materials[k] = "copper" coils = [ { "rings": range(2, 19, 2), # 'rings': range(10,19,2), # 'rings': [10], "c_type": "voltage", "c_value": 230.0 * numpy.sqrt(2.0), } ] wpi = 20 omega = 2 * pi * 10e3 return mesh, subdomains, coils, wpi, subdomain_materials, omega
def prolateGeometry(filename): from dolfin import XDMFFile, Mesh, MeshValueCollection, MeshTransformation xdmf_meshfile = "meshes/" + filename + ".xdmf" xdmf_meshfile_bm = "meshes/" + filename + "_bm.xdmf" mesh = Mesh() with XDMFFile(xdmf_meshfile) as infile: infile.read(mesh) mvc = MeshValueCollection("size_t", mesh, 2) with XDMFFile(xdmf_meshfile_bm) as infile: infile.read(mvc, "name_to_read") from dolfin import cpp markers = cpp.mesh.MeshFunctionSizet(mesh, mvc) ENDOCARD = 20 EPICARD = 10 BASE = 50 NONE = 99 MeshTransformation.scale(mesh, 1e-3) return mesh, markers, ENDOCARD, EPICARD, BASE, NONE
def currentloop(): base = "../meshes/2d/circle-in-halfcircle" mesh = Mesh(base + ".xml") subdomains = MeshFunction("size_t", mesh, base + "_physical_region.xml") subdomain_materials = {1: "copper", 2: "air"} coils = [{"rings": [1], "c_type": "voltage", "c_value": 230.0 * numpy.sqrt(2.0)}] wpi = None omega = 1.0e3 # According to # <http://hyperphysics.phy-astr.gsu.edu/hbase/magnetic/curloo.html>, # the magnitude of the magnetic field is # # |B| = mu0*I / (2*r0) # = mu0*V / (2*r0*R). # # at the center of the loop. With a copper wire, this is # # |B| = pi * 4e-7 * V / (2*r0*1.535356e-08) # ~ 40.9 * V/r0. # = 13.30350e3 # return mesh, subdomains, coils, wpi, subdomain_materials, omega
def make_mesh(vertices, cells, cell_type): '''Mesh from data by MeshEditor''' gdim = cell_type.geometric_dimension() assert vertices.shape[1] == gdim tdim = cell_type.topological_dimension() mesh = Mesh() editor = MeshEditor() editor.open(mesh, str(cell_type), tdim, gdim) editor.init_vertices(len(vertices)) editor.init_cells(len(cells)) for vi, x in enumerate(vertices): editor.add_vertex(vi, x) for ci, c in enumerate(cells): editor.add_cell(ci, *c) editor.close() return mesh
def create_mesh(lcar): geom = pygmsh.Geometry() cache_file = 'karman.msh' if os.path.isfile(cache_file): print('Using mesh from cache \'{}\'.'.format(cache_file)) points, cells, _, _, _ = meshio.read(cache_file) else: # slightly off-center circle circle = geom.add_circle([0.1, 1.0e-2, 0.0], 0.5 * obstacle_diameter, lcar, make_surface=False) geom.add_rectangle(x0, x1, y0, y1, 0.0, lcar, holes=[circle]) points, cells, _, _, _ = pygmsh.generate_mesh(geom) meshio.write(cache_file, points, cells) # https://fenicsproject.org/qa/12891/initialize-mesh-from-vertices-connectivities-at-once meshio.write('test.xml', points, cells) return Mesh('test.xml')
def get(self): """Build vertices from polar coordinates.""" angle, dist = self.values if len(angle) < 3: angle = np.array(range(int(angle[0]))) * 360.0 / angle[0] while len(dist) < len(angle): dist = dist * 2 dist = np.array(dist) sides = len(angle) mesh = Mesh() editor = MeshEditor() editor.open(mesh, 2, 2) editor.init_vertices(sides + 1) editor.init_cells(sides) editor.add_vertex(0, 0, 0) for i in range(1, sides + 1): editor.add_vertex(i, dist[i - 1] * cos(angle[i - 1] / 180.0 * pi), dist[i - 1] * sin(angle[i - 1] / 180.0 * pi)) for i in range(sides - 1): editor.add_cell(i, 0, i + 1, i + 2) editor.add_cell(sides - 1, 0, sides, 1) editor.close() return mesh
def get(self): """Eight cells.""" mesh = Mesh() editor = MeshEditor() editor.open(mesh, 3, 3) editor.init_vertices(7) editor.init_cells(8) editor.add_vertex(0, 1, 0, 0) editor.add_vertex(1, 0, 1, 0) editor.add_vertex(2, 0, 0, 1) editor.add_vertex(3, -1, 0, 0) editor.add_vertex(4, 0, -1, 0) editor.add_vertex(5, 0, 0, -1) editor.add_vertex(6, 0, 0, 0) editor.add_cell(0, 6, 0, 1, 2) editor.add_cell(1, 6, 0, 1, 5) editor.add_cell(2, 6, 0, 4, 2) editor.add_cell(3, 6, 0, 4, 5) editor.add_cell(4, 6, 3, 1, 2) editor.add_cell(5, 6, 3, 1, 5) editor.add_cell(6, 6, 3, 4, 2) editor.add_cell(7, 6, 3, 4, 5) editor.close() return mesh
def Lshape(x1, x2, x3, y1, y2, y3, h): """ (x1,y3) (x2,y3) (x2,y2) (x3,y2) (x1,y1) (x3,y1) """ mesh = Mesh() domain_vertices = [ Point(x1, y1), Point(x1, y3), Point(x2, y3), Point(x2, y2), Point(x3, y2), Point(x3, y1), Point(x1, y1) ] PolygonalMeshGenerator.generate(mesh, domain_vertices, h) return mesh
def vedoPlotter(pygmsh_ms): # Reading mesh data stored in .xdmf files. mesh = Mesh() with XDMFFile(pygmsh_ms) as infile: infile.read(mesh) # Define variational problem V = FunctionSpace(mesh, 'P', 1) u = Function(V) R_path = "Output_data" fU_in = XDMFFile(os.path.join(R_path, 'FuelRod_m.xdmf')) fU_in.read_checkpoint(u, "T", 0) axes_opts = dict( xyGrid=True, axesLineWidth=1, xTickColor='black', yTickColor='black', xMinorTicks=1, # number of minor ticks btw two major ticks yMinorTicks=1, # number of minor ticks btw two major ticks xLabelSize=0.02, # size of the numeric labels along axis yLabelSize=0.02, # offset of numeric labels ) # nipy_spectral, gnuplot plot(u, interactive=True, cmap='hot', axes=0, lw=2, scalarbar='vertical', wireframe=True, alpha=10., warpZfactor=0.) # warpZfactor=0.01 plot()
def convert(msh_file, h5_file, save_mvc=False): '''Temporary version of convertin from msh to h5''' root, _ = os.path.splitext(msh_file) assert os.path.splitext(msh_file)[1] == '.msh' assert os.path.splitext(h5_file)[1] == '.h5' # Get the xml mesh xml_file = '.'.join([root, 'xml']) subprocess.call(['dolfin-convert %s %s' % (msh_file, xml_file)], shell=True) # Success? assert os.path.exists(xml_file) mesh = Mesh(xml_file) out = HDF5File(mesh.mpi_comm(), h5_file, 'w') out.write(mesh, 'mesh') print('Mesh has %d cells' % mesh.num_cells()) print('Mesh size %g %g' % (mesh.hmin(), mesh.hmax())) # Save ALL data as facet_functions names = ('surfaces', 'volumes') if not save_mvc: for name, region in zip(names, ('facet_region.xml', 'physical_region.xml')): r_xml_file = '_'.join([root, region]) f = MeshFunction('size_t', mesh, r_xml_file) print('%d %s with 1' % (sum(1 for _ in SubsetIterator(f, 1)), name)) out.write(f, name) return True for name, region in zip(names, ('facet_region.xml', 'physical_region.xml')): r_xml_file = '_'.join([root, region]) f = MeshFunction('size_t', mesh, r_xml_file) # With mesh value collection we only store nonzero tags mvc = MeshValueCollection('size_t', mesh, f.dim()) # Fill fill_mvc_from_mf(f, mvc) # And save out.write(mvc, name) return True
elif platform.system() == "Darwin": os.system( "curl -L https://www.dropbox.com/s/d78g4cyjxl3ylay/cylinder.xml?dl=0 -o cylinder.xml" ) else: raise ImportError("Could not determine platform") # try: #os.system("gmsh mesh/cylinder.geo -2 -o mesh/cylinder.msh") #os.system("dolfin-convert mesh/cylinder.msh mesh/cylinder.xml") #os.system("rm mesh/cylinder.msh") # except RuntimeError: #os.system("wget -O cylinder.xml https://www.dropbox.com/s/d78g4cyjxl3ylay/cylinder.xml?dl=0") ##raise "Gmsh is required to run this demo" mesh = Mesh("cylinder.xml") H = 0.41 L = 2.2 D = 0.1 center = 0.2 cases = {1: {'Um': 0.3, 'Re': 20.0}, 2: {'Um': 1.5, 'Re': 100.0}} # Specify boundary conditions Inlet = AutoSubDomain(lambda x, on_bnd: on_bnd and x[0] < 1e-8) Wall = AutoSubDomain(lambda x, on_bnd: on_bnd and near(x[1] * (H - x[1]), 0)) Cyl = AutoSubDomain(lambda x, on_bnd: (on_bnd and x[0] > 1e-6 and x[0] < 1 and x[1] < 3 * H / 4 and x[1] > H / 4)) Outlet = AutoSubDomain(lambda x, on_bnd: on_bnd and x[0] > L - 1e-8)
def coil_in_box(): mesh = Mesh("../meshes/2d/coil-in-box.xml") f = Constant(0.0) # Define mesh and boundaries. class LeftBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] < GMSH_EPS left_boundary = LeftBoundary() class RightBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] > 2.5 - GMSH_EPS right_boundary = RightBoundary() class LowerBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[1] < GMSH_EPS lower_boundary = LowerBoundary() class UpperBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[1] > 0.4 - GMSH_EPS upper_boundary = UpperBoundary() class CoilBoundary(SubDomain): def inside(self, x, on_boundary): return ( on_boundary and x[0] > GMSH_EPS and x[0] < 2.5 - GMSH_EPS and x[1] > GMSH_EPS and x[1] < 0.4 - GMSH_EPS ) coil_boundary = CoilBoundary() # heater_temp = 380.0 # room_temp = 293.0 # bcs = [(coil_boundary, heater_temp), # (left_boundary, room_temp), # (right_boundary, room_temp), # (upper_boundary, room_temp), # (lower_boundary, room_temp) # ] boundaries = {} boundaries["left"] = left_boundary boundaries["right"] = right_boundary boundaries["upper"] = upper_boundary boundaries["lower"] = lower_boundary boundaries["coil"] = coil_boundary boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundaries.set_all(0) left_boundary.mark(boundaries, 1) right_boundary.mark(boundaries, 2) upper_boundary.mark(boundaries, 3) lower_boundary.mark(boundaries, 4) coil_boundary.mark(boundaries, 5) boundary_indices = {"left": 1, "right": 2, "top": 3, "bottom": 4, "coil": 5} theta0 = Constant(293.0) return mesh, f, boundaries, boundary_indices, theta0
def convert(ifilename, handler): """ Convert from Abaqus. The Abaqus format first defines a node block, then there should be a number of elements containing these nodes. """ # Dictionary of nodes (maps node id to coordinates) nodes = {} # Dictionary of elements (maps cell id to list of cell nodes) elems = {} # Lists of nodes for given name (key) node_sets = {} # Lists of cells for given name (key) cell_sets = {} # Lists of surfaces for given name (key) in the format: # {'SS1': [set(['SS1_S1', 'S1']), set(['SS1_S4', 'S4'])]}, # where SS1 is the name of the surface, SS1_S1 is the name of the # cell list whose first face is to be selected, ... surface_sets = {} # Open file Abaqus file csv_file = csv.reader(open(ifilename, 'rb'), delimiter=',', skipinitialspace=True) node_set_name = None generate = None # Set intial state state state = State.Init # Read data from input file for l in csv_file: # Sanity check if (len(l) == 0): print "Ooops, zero length." if l[0].startswith('**'): # Pass over comments continue elif l[0].startswith('*'): # Have a keyword state = State.Unknown if l[0].lower() == "*heading": state = State.ReadHeading elif l[0].lower() == "*part": part_name = _read_part_name(l) elif l[0].lower() == "*end part": state = State.Invalid elif l[0].lower() == "*node": node_set_name = _create_node_list_entry(node_sets, l) state = State.ReadNodes elif l[0].lower() == "*element": cell_type, cell_set_name = _read_element_keywords(cell_sets, l) state = State.ReadCells elif l[0].lower() == "*nset": node_set_name, generate = _read_nset_keywords(node_sets, l) state = State.ReadNodeSet elif l[0].lower() == "*elset": cell_set_name, generate = _read_elset_keywords(cell_sets, l) if generate: print "WARNING: generation of *elsets not tested." state = State.ReadCellSet elif l[0].lower() == "*surface": surface_set_name, generate = _read_surface_keywords(surface_sets, l) state = State.ReadSurfaceSet else: print "WARNING: unrecognised Abaqus input keyword:", l[0] state = State.Unknown else: if state == State.ReadHeading: model_name = _read_heading(l) elif state == State.ReadNodes: node_id = int(l[0]) - 1 coords = [float(c) for c in l[1:]] nodes[node_id] = coords if node_set_name is not None: node_sets[node_set_name].add(node_id) elif state == State.ReadCells: cell_id = int(l[0]) - 1 cell_connectivity = [int(v) - 1 for v in l[1:]] elems[cell_id] = cell_connectivity if cell_set_name is not None: cell_sets[cell_set_name].add(cell_id) elif state == State.ReadNodeSet: try: if generate: n0, n1, increment = l node_range = range(int(n0) - 1, int(n1) - 1, int(increment)) node_range.append(int(n1) - 1) node_sets[node_set_name].update(node_range) else: # Strip empty term at end of list, if present if l[-1] == '': l.pop(-1) node_range = [int(n) - 1 for n in l] node_sets[node_set_name].update(node_range) except: print "WARNING: Non-integer node sets not yet supported." elif state == State.ReadCellSet: try: if generate: n0, n1, increment = l cell_range = range(int(n0) - 1, int(n1) - 1, int(increment)) cell_range.append(int(n1) - 1) cell_sets[cell_set_name].update(cell_range) else: # Strip empty term at end of list, if present if l[-1] == '': l.pop(-1) cell_range = [int(n) - 1 for n in l] cell_sets[cell_set_name].update(cell_range) except: print "WARNING: Non-integer element sets not yet supported." elif state == State.ReadSurfaceSet: # Strip empty term at end of list, if present if l[-1] == '': l.pop(-1) surface_sets[surface_set_name].update([tuple(l)]) elif state == State.Invalid: # part raise StandardError("Inavlid Abaqus parser state..") # Close CSV object del csv_file # Write data to XML file # Note that vertices/cells must be consecutively numbered, which # isn't necessarily the case in Abaqus. Therefore we enumerate and # translate original IDs to sequence indexes if gaps are present. # FIXME handler.set_mesh_type("tetrahedron", 3) process_facets = len(surface_sets) > 0 if process_facets: try: from dolfin import MeshEditor, Mesh except ImportError: _error("DOLFIN must be installed to handle Abaqus boundary regions") mesh = Mesh() mesh_editor = MeshEditor() mesh_editor.open(mesh, 3, 3) node_ids_order = {} # Check for gaps in vertex numbering node_ids = nodes.keys() if len(node_ids) > 0: vertex_gap = (min(node_ids) != 0 or max(node_ids) != len(node_ids) - 1) for x, y in enumerate(node_ids): node_ids_order[y]= x # Maps Abaqus IDs to Dolfin IDs else: vertex_gap = True # Check for gaps in cell numbering elemids = elems.keys() if len(elemids) > 0: cell_gap = (min(elemids) != 0 or max(elemids) != len(elemids) - 1) else: cell_gap = True # Write vertices to XML file handler.start_vertices(len(nodes)) if process_facets: mesh_editor.init_vertices (len(nodes)) if not vertex_gap: for v_id, v_coords in nodes.items(): handler.add_vertex(v_id, v_coords) if process_facets: mesh_editor.add_vertex(v_id, np.array(v_coords, dtype=np.float_)) else: for idx, (v_id, v_coords) in enumerate(nodes.items()): handler.add_vertex(idx, v_coords) if process_facets: mesh_editor.add_vertex(idx, np.array(v_coords, dtype=np.float_)) handler.end_vertices() # Write cells to XML file handler.start_cells(len(elems)) if process_facets: mesh_editor.init_cells(len(elems)) if not vertex_gap and not cell_gap: for c_index, c_data in elems.items(): for v_id in c_data: if not (0 <= v_id < len(nodes)): handler.error("Element %s references non-existent node %s" % (c_index, v_id)) handler.add_cell(c_index, c_data) if process_facets: c_data_tmp = np.array(c_data) c_data_tmp.sort() mesh_editor.add_cell(c_index, np.array(c_data_tmp, dtype=np.uintp)) elif not vertex_gap and cell_gap: for idx, (c_index, c_data) in enumerate(elems.items()): for v_id in c_data: if not (0 <= v_id < len(nodes)): handler.error("Element %s references non-existent node %s" % (c_index, v_id)) handler.add_cell(idx, c_data) if process_facets: c_data_tmp = np.array(c_data) c_data_tmp.sort() mesh_editor.add_cell(idx, np.array(c_data_tmp, dtype=np.uintp)) else: for idx, (c_id, c_data) in enumerate(elems.items()): c_nodes = [] for v_id in c_data: try: c_nodes.append(node_ids_order[v_id]) except ValueError: handler.error("Element %s references non-existent node %s" % (c_id, v_id)) handler.add_cell(idx, c_nodes) if process_facets: c_nodes.sort() mesh_editor.add_cell(idx, np.array(c_nodes, dtype=np.uintp)) handler.end_cells() # Write MeshValueCollections to XML file handler.start_domains() # Build a abaqus node ID -> dolfin cell ID map (which is not unique but that is irrelevant here) # and its local entity. if len(node_sets.items()) > 0: node_cell_map = {} for c_dolfin_index, (c_index, c_data) in enumerate(elems.items()): c_data_tmp = np.array(c_data) c_data_tmp.sort() for local_entity, n_index in enumerate(c_data_tmp): node_cell_map[n_index] = (c_dolfin_index, local_entity) # Write vertex/node sets dim = 0 for value, (name, node_set) in enumerate(node_sets.items()): handler.start_mesh_value_collection(name, dim, len(node_set), "uint") for node in node_set: try: cell, local_entity = node_cell_map[node] handler.add_entity_mesh_value_collection(dim, cell, value, local_entity=local_entity) except KeyError: print "Warning: Boundary references non-existent node %s" % node handler.end_mesh_value_collection() # Write cell/element sets dim = 3 for name, s in cell_sets.items(): handler.start_mesh_value_collection(name, dim, len(s), "uint") for cell in s: handler.add_entity_mesh_value_collection(dim, cell, 0) handler.end_mesh_value_collection() # Write surface sets if process_facets: dim = 2 nodes_facet_map = _nodes_facet_map(mesh) data = [int(0)] * mesh.num_facets() S1 = [0, 1, 2] S2 = [0, 3, 1] S3 = [1, 3, 2] S4 = [2, 3, 0] node_selector = {'S1': S1, 'S2': S2, 'S3': S3, 'S4': S4, } for index, (name, s) in enumerate(surface_sets.items()): cell_face_list = [] for cell_set_name, face_index in s: cell_face_list += [(cell, face_index) for cell in cell_sets[cell_set_name]] for cell, face in cell_face_list: cell_nodes = elems[cell] # Extract the face nodes face_nodes = [cell_nodes[i] for i in node_selector[face]] dolfin_face_nodes = [node_ids_order[n] for n in face_nodes] dolfin_face_nodes.sort() # Convert the face_nodes to dolfin IDs face_id = nodes_facet_map[tuple(dolfin_face_nodes)] data[face_id] = index + 1 # Create and initialise the mesh function handler.start_meshfunction("facet_region", dim, mesh.num_facets() ) for index, physical_region in enumerate (data): handler.add_entity_meshfunction(index, physical_region) handler.end_meshfunction() handler.end_domains()
def gmsh2xml(ifilename, handler): """Convert between .gmsh v2.0 format (http://www.geuz.org/gmsh/) and .xml, parser implemented as a state machine: 0 = read 'MeshFormat' 1 = read mesh format data 2 = read 'EndMeshFormat' 3 = read 'Nodes' 4 = read number of vertices 5 = read vertices 6 = read 'EndNodes' 7 = read 'Elements' 8 = read number of cells 9 = read cells 10 = done Afterwards, extract physical region numbers if they are defined in the mesh file as a mesh function. """ print "Converting from Gmsh format (.msh, .gmsh) to DOLFIN XML format" # The dimension of the gmsh element types supported here as well as the dolfin cell types for each dimension gmsh_dim = {15: 0, 1: 1, 2: 2, 4: 3} cell_type_for_dim = {1: "interval", 2: "triangle", 3: "tetrahedron" } # the gmsh element types supported for conversion supported_gmsh_element_types = [1, 2, 4, 15] # Open files ifile = open(ifilename, "r") # Scan file for cell type cell_type = None highest_dim = 0 line = ifile.readline() while line: # Remove newline if line[-1] == "\n": line = line[:-1] # Read dimension if line.find("$Elements") == 0: line = ifile.readline() num_elements = int(line) if num_elements == 0: _error("No elements found in gmsh file.") line = ifile.readline() # Now iterate through elements to find largest dimension. Gmsh # format might include elements of lower dimensions in the element list. # We also need to count number of elements of correct dimensions. # Also determine which vertices are not used. dim_count = {0: 0, 1: 0, 2: 0, 3: 0} vertices_used_for_dim = {0: [], 1: [], 2: [], 3: []} # Array used to store gmsh tags for 1D (type 1/line), 2D (type 2/triangular) elements and 3D (type 4/tet) elements tags_for_dim = {0: [], 1: [], 2: [], 3: []} while line.find("$EndElements") == -1: element = line.split() elem_type = int(element[1]) num_tags = int(element[2]) if elem_type in supported_gmsh_element_types: dim = gmsh_dim[elem_type] if highest_dim < dim: highest_dim = dim node_num_list = [int(node) for node in element[3 + num_tags:]] vertices_used_for_dim[dim].extend(node_num_list) if num_tags > 0: tags_for_dim[dim].append(tuple(int(tag) for tag in element[3:3+num_tags])) dim_count[dim] += 1 else: #TODO: output a warning here. "gmsh element type %d not supported" % elem_type pass line = ifile.readline() else: # Read next line line = ifile.readline() # Check that we got the cell type and set num_cells_counted if highest_dim == 0: _error("Unable to find cells of supported type.") num_cells_counted = dim_count[highest_dim] vertex_set = set(vertices_used_for_dim[highest_dim]) vertices_used_for_dim[highest_dim] = None vertex_dict = {} for n,v in enumerate(vertex_set): vertex_dict[v] = n # Step to beginning of file ifile.seek(0) # Set mesh type handler.set_mesh_type(cell_type_for_dim[highest_dim], highest_dim) # Initialise node list (gmsh does not export all vertexes in order) nodelist = {} # Current state state = 0 # Write data num_vertices_read = 0 num_cells_read = 0 # Only import the dolfin objects if facet markings exist process_facets = False if len(tags_for_dim[highest_dim-1]) > 0: # first construct the mesh try: from dolfin import MeshEditor, Mesh except ImportError: _error("DOLFIN must be installed to handle Gmsh boundary regions") mesh = Mesh() mesh_editor = MeshEditor () mesh_editor.open( mesh, highest_dim, highest_dim ) process_facets = True else: # TODO: Output a warning or an error here me = None while state != 10: # Read next line line = ifile.readline() if not line: break # Skip comments if line[0] == '#': continue # Remove newline if line[-1] == "\n": line = line[:-1] if state == 0: if line == "$MeshFormat": state = 1 elif state == 1: (version, file_type, data_size) = line.split() state = 2 elif state == 2: if line == "$EndMeshFormat": state = 3 elif state == 3: if line == "$Nodes": state = 4 elif state == 4: num_vertices = len(vertex_dict) handler.start_vertices(num_vertices) if process_facets: mesh_editor.init_vertices ( num_vertices ) state = 5 elif state == 5: (node_no, x, y, z) = line.split() node_no = int(node_no) x,y,z = [float(xx) for xx in (x,y,z)] if vertex_dict.has_key(node_no): node_no = vertex_dict[node_no] else: continue nodelist[int(node_no)] = num_vertices_read handler.add_vertex(num_vertices_read, [x, y, z]) if process_facets: if highest_dim == 1: coords = numpy.array([x]) elif highest_dim == 2: coords = numpy.array([x, y]) elif highest_dim == 3: coords = numpy.array([x, y, z]) mesh_editor.add_vertex(num_vertices_read, coords) num_vertices_read +=1 if num_vertices == num_vertices_read: handler.end_vertices() state = 6 elif state == 6: if line == "$EndNodes": state = 7 elif state == 7: if line == "$Elements": state = 8 elif state == 8: handler.start_cells(num_cells_counted) if process_facets: mesh_editor.init_cells( num_cells_counted ) state = 9 elif state == 9: element = line.split() elem_type = int(element[1]) num_tags = int(element[2]) if elem_type in supported_gmsh_element_types: dim = gmsh_dim[elem_type] else: dim = 0 if dim == highest_dim: node_num_list = [vertex_dict[int(node)] for node in element[3 + num_tags:]] for node in node_num_list: if not node in nodelist: _error("Vertex %d of %s %d not previously defined." % (node, cell_type_for_dim[dim], num_cells_read)) cell_nodes = [nodelist[n] for n in node_num_list] handler.add_cell(num_cells_read, cell_nodes) if process_facets: cell_nodes = numpy.array([nodelist[n] for n in node_num_list], dtype=numpy.uintp) mesh_editor.add_cell(num_cells_read, cell_nodes) num_cells_read +=1 if num_cells_counted == num_cells_read: handler.end_cells() if process_facets: mesh_editor.close() state = 10 elif state == 10: break # Write mesh function based on the Physical Regions defined by # gmsh, but only if they are not all zero. All zero physical # regions indicate that no physical regions were defined. if highest_dim not in [1,2,3]: _error("Gmsh tags not supported for dimension %i. Probably a bug" % dim) tags = tags_for_dim[highest_dim] physical_regions = tuple(tag[0] for tag in tags) if not all(tag == 0 for tag in physical_regions): handler.start_meshfunction("physical_region", dim, num_cells_counted) for i, physical_region in enumerate(physical_regions): handler.add_entity_meshfunction(i, physical_region) handler.end_meshfunction() # Now process the facet markers tags = tags_for_dim[highest_dim-1] if (len(tags) > 0) and (mesh is not None): physical_regions = tuple(tag[0] for tag in tags) if not all(tag == 0 for tag in physical_regions): mesh.init(highest_dim-1,0) # Get the facet-node connectivity information (reshape as a row of node indices per facet) if highest_dim==1: # for 1d meshes the mesh topology returns the vertex to vertex map, which isn't what we want # as facets are vertices facets_as_nodes = numpy.array([[i] for i in range(mesh.num_facets())]) else: facets_as_nodes = mesh.topology()(highest_dim-1,0)().reshape ( mesh.num_facets(), highest_dim ) # Build the reverse map nodes_as_facets = {} for facet in range(mesh.num_facets()): nodes_as_facets[tuple(facets_as_nodes[facet,:])] = facet data = [int(0*k) for k in range(mesh.num_facets()) ] for i, physical_region in enumerate(physical_regions): nodes = [n-1 for n in vertices_used_for_dim[highest_dim-1][highest_dim*i:(highest_dim*i+highest_dim)]] nodes.sort() if physical_region != 0: try: index = nodes_as_facets[tuple(nodes)] data[index] = physical_region except IndexError: raise Exception ( "The facet (%d) was not found to mark: %s" % (i, nodes) ) # # Create and initialise the mesh function handler.start_meshfunction("facet_region", highest_dim-1, mesh.num_facets() ) for index, physical_region in enumerate ( data ): handler.add_entity_meshfunction(index, physical_region) handler.end_meshfunction() # Check that we got all data if state == 10: print "Conversion done" else: _error("Missing data, unable to convert \n\ Did you use version 2.0 of the gmsh file format?") # Close files ifile.close()
# Rossby radius. LR=c/params["f"] class InitialConditions(Expression): def __init__(self): pass def eval(self, values, X): r=(X[0]**2+X[1]**2)**0.5 if r>0.0001: values[0]=-0.05*c*exp((r-r0)/LR)*X[0]/r*X[1]/r values[1]= 0.05*c*exp((r-r0)/LR)*X[0]/r*X[0]/r values[2]= 0.05*exp((r-r0)/LR)*X[0]/r else: values[0]=0. values[1]=0. values[2]=0. def value_shape(self): return (3,) try: mesh=Mesh("basin.xml") except RuntimeError: import sys import os.path mesh=Mesh(os.path.dirname(sys.argv[0]) + os.path.sep + "basin.xml") mesh.order() mesh.init()
def get_antarctica_coarse(): filename = inspect.getframeinfo(inspect.currentframe()).filename home = os.path.dirname(os.path.abspath(filename)) mesh = Mesh(home + '/antarctica/antarctica_50H_5l.xml') mesh.coordinates()[:,2] /= 1000.0 return mesh
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 _load_mesh(self): with XDMFFile(self._mesh_filename) as fh: self._mesh = Mesh() fh.read(self._mesh)
import numpy from dolfin import Mesh mesh = Mesh("mesh.xml.gz") E = mesh.cells() M = numpy.fromfile('materials.np'); I = -numpy.ones(mesh.num_vertices()) for i in range(6): edx = numpy.nonzero((M>10*(i+1))*(M<10*(i+2)))[0] idx = (numpy.unique(E[edx,0:3])).astype(int) I[idx] = i*0.2 edx = numpy.nonzero(M==7)[0] idx = (numpy.unique(E[edx,0:3])).astype(int) I[idx] = -2; from viper import Viper pv = Viper(mesh, I) pv.interactive()
class TestIonTag(unittest.TestCase): def setUp(self, *args, **kwargs): self.mesh = Mesh() editor = MeshEditor() editor.open(self.mesh, 2, 2) # topo_dim = 2, geom dim = 2 editor.init_vertices(6) editor.init_cells(2) vertex_0 = Vertex(self.mesh, 0) vertex_1 = Vertex(self.mesh, 1) vertex_2 = Vertex(self.mesh, 2) vertex_3 = Vertex(self.mesh, 3) vertex_4 = Vertex(self.mesh, 4) vertex_5 = Vertex(self.mesh, 5) editor.add_cell(0,1,2,3) editor.add_cell(1,0,2,3) editor.close() def test_init(self): # test possible arguments and failure cases... #@todo implement the test once we have exception handling in the init method # pass in a string for values and see what happens values = 'i am just a string' t = IonTag('foo',3,'int', self.mesh) v = MeshEntity(self.mesh,0,1) try: t[v] = values except ValueError: pass else: raise AssertionError('It should have raised a value error!') def test_get_set_del(self): #Test the getter, setter and delete method values = [1,2,3] t = IonTag('foo',3,'int', self.mesh) for v in vertices(self.mesh): # test the setter t[v] = values # choose an entity in the mesh v = MeshEntity(self.mesh,0,1) # test the getter self.assertTrue((t[v] == values).all()) #--------------------------------------------------------------------------------------- # Check delete of a tag entry (for an entity) #--------------------------------------------------------------------------------------- # choose an entity to delete entity_tuple = (v.dim(),v.index()) # check that tag has the entity, v, in it self.assertTrue(t._entity_values.has_key(entity_tuple)) # delete a tag entry for an entity del t[entity_tuple] # check that the tag no longer has the entity, v, in it self.assertFalse(t._entity_values.has_key(entity_tuple)) #--------------------------------------------------------------------------------------- # Add less number of values than the size defined in the tag object #--------------------------------------------------------------------------------------- values = [1] t = IonTag('foo',3,'int', self.mesh) v = MeshEntity(self.mesh,0,1) #@todo check to see why self.assertRaises is not working for unittest: # with self.assertRaises(ValueError): # t[v] = values try: t[v] = values except ValueError: pass else: raise AssertionError('A Value Error should have been raised!') #--------------------------------------------------------------------------------------- # Add more number of values that the size defined in the tag object #--------------------------------------------------------------------------------------- values = [1,2,3,4] size = 2 t = IonTag('foo',size,'int', self.mesh) v = MeshEntity(self.mesh,0,1) t[v] = values for key, value in t.iteritems(): self.assertEqual(len(value), size) def test_len(self): t = IonTag('foo',3,'int', self.mesh) # we create a tag entry for every vertex of the mesh for v in vertices(self.mesh): # testing setter t[v] = [1,2,3] # we check that the number of tag entries is the same as the number we created self.assertEqual(len(t), self.mesh.num_vertices()) def test_contains(self): values = [1,2,3] t = IonTag('foo',3,'int', self.mesh) for v in vertices(self.mesh): # testing setter t[v] = values v = MeshEntity(self.mesh,0,1) # testing getter self.assertTrue((t[v] == values).all()) #--------------------------------------------------------------------------------------- # Delete a tag entry (for an entity) #--------------------------------------------------------------------------------------- # choose an entity to delete entity_tuple = (v.dim(),v.index()) # check that tag has the entity, v, in it self.assertTrue(t.__contains__(entity_tuple)) del t._entity_values[entity_tuple] # check that the tag no longer has the entity, v, in it self.assertFalse(t.__contains__(entity_tuple)) def test_len(self): # Initial step: Feed in values to the vertices in the mesh t = IonTag('foo',1,'int', self.mesh) for x,v in enumerate(vertices(self.mesh)): t[v] = (x,) # test len self.assertEqual(len(t), self.mesh.num_vertices()) def test_types(self): # test with different types: #@todo for each type check that input is cast to type #--------------------------------------------------------------------------------------- # Ints #--------------------------------------------------------------------------------------- t = IonTag('foo',3,'int', self.mesh) self.assertEqual(t._type, 'int') # Add some float values to the tag, and check if they are converted to # int tag values values = [1.23,2.232,3.323] # a list of int values v = MeshEntity(self.mesh,0,1) t[v] = values for key, item in t.iteritems(): for num in item: self.assertTrue(isinstance(num, int)) #--------------------------------------------------------------------------------------- # Floats #--------------------------------------------------------------------------------------- t = IonTag('foo',3,'float', self.mesh) self.assertEqual(t._type, 'float') # Add some int values to the tag, and check if they are converted to # float tag values values = [1,2,3] # a list of int values v = MeshEntity(self.mesh,0,1) t[v] = values for key, item in t.iteritems(): for num in item: self.assertTrue(isinstance(num, float)) # now pass in complex values values = [complex(1,2), complex(3,4), complex(5,6), complex(7,8)] try: t[v] = values except TypeError: pass else: raise AssertionError('Did not raise type error. Python should complain when converting from complex to float') for key, item in t.iteritems(): for num in item: self.assertTrue(isinstance(num, float)) #--------------------------------------------------------------------------------------- # Complex #--------------------------------------------------------------------------------------- t = IonTag('foo',3,'complex', self.mesh) self.assertEqual(t._type, 'complex') values = [1,2,3,4,5] v = MeshEntity(self.mesh,0,1) t[v] = values for key, item in t.iteritems(): for num in item: self.assertTrue(isinstance(num, complex)) #--------------------------------------------------------------------------------------- # String #--------------------------------------------------------------------------------------- #@todo: Strings cannot be passed in. This is because it is a variable sized data type, and numpy cannot handle it # t = IonTag('foo',3,'string', self.mesh) # self.assertEqual(t._type, 'string') # # v = MeshEntity(self.mesh,0,1) # # # passing in a string # values = ['string1', ' string2'] # t[v] = values # # # passing in a number # values = [3,4] # try: # t[v] = values # except ValueError: # pass # else: # raise AssertionError('Numpy should complain') # # # for key, item in t.iteritems(): # for num in item: # self.assertTrue(isinstance(num, str)) #--------------------------------------------------------------------------------------- # User defined #--------------------------------------------------------------------------------------- # t = IonTag('foo',3,'user_defined', self.mesh) # self.assertEqual(t._type, 'user_defined') #--------------------------------------------------------------------------------------- # Object #--------------------------------------------------------------------------------------- #@todo: numpy cannot create object arrays from iterator. so objects cannot be passed in as values # t = IonTag('foo',3,'object', self.mesh) # self.assertEqual(t._type, 'object') # # values = [1,2,3,4] # # v = MeshEntity(self.mesh,0,1) # t[v] = values # # for key, item in t.iteritems(): # for num in item: # self.assertTrue(isinstance(num, object)) def test_iter(self): # test the iterator and verify that the correct type is passed back #------------------------------------------------------------ # Initial step: Feed in values to the vertices in the mesh #------------------------------------------------------------ t = IonTag('foo',1,'int', self.mesh) for x,v in enumerate(vertices(self.mesh)): t[v] = (x,) #------------------------------------------------------------ # Test the iteration over the tags #------------------------------------------------------------ for key, item in t.iteritems(): self.assertEqual(t[ key ], item ) self.assertTrue(isinstance(key, MeshEntity)) self.assertTrue(isinstance(item[0], int )) def test_properties(self): # contains, len etc... #@todo may be we can remove this test method as the contains() and len() methods have their own separate test methods pass
def get_greenland_detailed(): filename = inspect.getframeinfo(inspect.currentframe()).filename home = os.path.dirname(os.path.abspath(filename)) mesh = Mesh(home + '/greenland/greenland_detailed_mesh.xml') mesh.coordinates()[:,2] /= 100000.0 return mesh
def get_circle(): filename = inspect.getframeinfo(inspect.currentframe()).filename home = os.path.dirname(os.path.abspath(filename)) mesh = Mesh(home + '/test/circle.xml') mesh.coordinates()[:,2] /= 1000.0 return mesh
import numpy as np import pylab as p from dolfin import Mesh from finmag.sim.llg import LLG from finmag.drivers.llg_integrator import llg_integrator # Create mesh mu = 1e-9 mesh = Mesh("coarse_bar.xml.gz") #mesh = Mesh("bar.xml.gz") # Setup LLG llg = LLG(mesh, unit_length=mu) llg.Ms = 0.86e6 llg.A = 13.0e-12 llg.alpha = 0.5 llg.set_m((1, 0, 1)) llg.setup(use_exchange=True, use_dmi=False, use_demag=True, demag_method="FK") # Set up time integrator integrator = llg_integrator(llg, llg.m) dt = 5e-12 ###### # After ten time steps, plot the energy density # from z=0 to z=100 through the center of the body. ###### # Integrate integrator.run_until(dt * 10) exch = llg.exchange.energy_density_function()
def __init__(self): # https://fenicsproject.org/qa/12891/initialize-mesh-from-vertices-connectivities-at-once points, cells, _, cell_data, _ = meshes.ball_in_tube_cyl.generate() # 2018.1 # self.mesh = Mesh( # dolfin.mpi_comm_world(), dolfin.cpp.mesh.CellType.Type_triangle, # points[:, :2], cells['triangle'] # ) with TemporaryDirectory() as temp_dir: tmp_filename = os.path.join(temp_dir, "test.xml") meshio.write_points_cells( tmp_filename, points, cells, cell_data=cell_data, file_format="dolfin-xml", ) self.mesh = Mesh(tmp_filename) V0_element = FiniteElement("CG", self.mesh.ufl_cell(), 2) V1_element = FiniteElement("B", self.mesh.ufl_cell(), 3) self.W = FunctionSpace(self.mesh, V0_element * V1_element) self.P = FunctionSpace(self.mesh, "CG", 1) # Define mesh and boundaries. class LeftBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[0] < GMSH_EPS left_boundary = LeftBoundary() class RightBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[0] > 1.0 - GMSH_EPS right_boundary = RightBoundary() class LowerBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[1] < GMSH_EPS lower_boundary = LowerBoundary() # class UpperBoundary(SubDomain): # # pylint: disable=no-self-use # def inside(self, x, on_boundary): # return on_boundary and x[1] > 5.0-GMSH_EPS class CoilBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): # One has to pay a little bit of attention when defining the # coil boundary; it's easy to miss the edges closest to x[0]=0. return ( on_boundary and x[1] > 1.0 - GMSH_EPS and x[1] < 2.0 + GMSH_EPS and x[0] < 1.0 - GMSH_EPS ) coil_boundary = CoilBoundary() self.u_bcs = [ DirichletBC(self.W, (0.0, 0.0), right_boundary), DirichletBC(self.W.sub(0), 0.0, left_boundary), DirichletBC(self.W, (0.0, 0.0), lower_boundary), DirichletBC(self.W, (0.0, 0.0), coil_boundary), ] self.p_bcs = [] # self.p_bcs = [DirichletBC(Q, 0.0, upper_boundary)] return