def __init__(self, x0, y0, z0, R, n): class SphereSurface(SubDomain): def inside(self, x, on_boundary): return on_boundary class X_Symmetric(SubDomain): def inside(self, x, on_boundary): return near(x[0], x0) class Y_Symmetric(SubDomain): def inside(self, x, on_boundary): return near(x[1], y0) class Z_Symmetric(SubDomain): def inside(self, x, on_boundary): return near(x[2], z0) self.geometry = Sphere(Point(x0, y0, z0), R, segments=n) - Box(Point(x0 + R, y0, z0 - R), Point(x0 - R, y0 - R, z0 + R)) - Box(Point(x0 - R, y0 + R, z0), Point(x0 + R, y0, z0 - R)) - Box(Point(x0, y0, z0), Point(x0 - R, y0 + R, z0 + R)) self.mesh = generate_mesh(self.geometry, n) self.domains = MeshFunction("size_t", self.mesh, self.mesh.topology().dim()) self.domains.set_all(0) self.dx = Measure('dx', domain=self.mesh, subdomain_data=self.domains) self.boundaries = MeshFunction("size_t", self.mesh, self.mesh.topology().dim()-1) self.boundaries.set_all(0) self.sphereSurface = SphereSurface() self.sphereSurface.mark(self.boundaries, 1) self.x_symmetric = X_Symmetric() self.x_symmetric.mark(self.boundaries, 2) self.y_symmetric = Y_Symmetric() self.y_symmetric.mark(self.boundaries, 3) self.z_symmetric = Z_Symmetric() self.z_symmetric.mark(self.boundaries, 4) self.ds = Measure('ds', domain=self.mesh, subdomain_data=self.boundaries) self.dS = Measure('dS', domain=self.mesh, subdomain_data=self.boundaries)
def test_save_mesh_value_collection(tempdir, encoding, data_type): dtype_str, dtype = data_type mesh = UnitCubeMesh(MPI.comm_world, 4, 4, 4) tdim = mesh.topology.dim meshfn = MeshFunction(dtype_str, mesh, mesh.topology.dim, False) meshfn.name = "volume_marker" mp = cpp.mesh.midpoints(mesh, tdim, range(mesh.num_entities(tdim))) for i in range(mesh.num_cells()): if mp[i, 1] > 0.1: meshfn.values[i] = 1 if mp[i, 1] > 0.9: meshfn.values[i] = 2 for mvc_dim in range(0, tdim + 1): mvc = MeshValueCollection(dtype_str, mesh, mvc_dim) tag = "dim_{}_marker".format(mvc_dim) mvc.name = tag mesh.create_connectivity(mvc_dim, tdim) mp = cpp.mesh.midpoints(mesh, mvc_dim, range(mesh.num_entities(mvc_dim))) for e in range(mesh.num_entities(mvc_dim)): if (mp[e, 0] > 0.5): mvc.set_value(e, dtype(1)) filename = os.path.join(tempdir, "mvc_{}.xdmf".format(mvc_dim)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as xdmf: xdmf.write(meshfn) xdmf.write(mvc) with XDMFFile(mesh.mpi_comm(), filename) as xdmf: read_function = getattr(xdmf, "read_mvc_" + dtype_str) mvc = read_function(mesh, tag)
def create(mesh, domain_ids, invert=False): """ Creates a wrapped mesh from a super mesh for a given collection of domain IDs. *Arguments* mesh (:class:`dolfin.Mesh`) The mesh. domain_ids (:class:`[int]`) List of domain IDs invert (:class:`bool`) Invert list of domain IDs *Returns* :class:`WrappedMesh` The wrapped mesh """ if invert or isinstance(domain_ids, list) or isinstance( domain_ids, tuple): if isinstance(domain_ids, int): domain_ids = (domain_ids, ) subdomains = MeshFunction('size_t', mesh, 3, mesh.domains()) combined_subdomains = CellFunction("size_t", mesh, 0) for domain_id in domain_ids: combined_subdomains.array()[subdomains.array() == domain_id] = 1 submesh = SubMesh(mesh, combined_subdomains, 0 if invert else 1) else: submesh = SubMesh(mesh, domain_ids) submesh.__class__ = WrappedMesh submesh._init(mesh) return submesh
def load_data(mesh, mesh_f, dim, data): ''' Represent mesh_f over dim entities of mesh as collection of vertices. Can have mesh as mesh function or (h5_file, data_set) ''' try: h5_file, data_set = mesh_f mf = MeshFunction('size_t', mesh, dim, 0) h5_file.read(mf, data_set) except ValueError: mf = mesh_f data_set = '%d dim entites' % mf.dim() # Mapf for encoding entities as vertices mesh.init(dim, 0) e2v = mesh.topology()(dim, 0) tags = set(mf.array()) # Don't encode zero - we initialize to it if 0 in tags: tags.remove(0) info('%s evolves tags %r' % (data_set, tags)) for tag in tags: data[(dim, tag)] = np.array([e2v(e.index()) for e in SubsetIterator(mf, tag)], dtype='uintp') return data
def test_save_1d_mesh(tempdir, encoding): filename = os.path.join(tempdir, "mf_1D.xdmf") mesh = UnitIntervalMesh(MPI.comm_world, 32) mf = MeshFunction("size_t", mesh, mesh.topology.dim, 0) mf.values[:] = numpy.arange(mesh.num_entities(1)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(mf)
def boundaries(mesh): boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0) for f in facets(mesh): boundaries.array()[f.index()] = 0 for v in vertices(f): boundaries.array()[f.index()] += v.global_index() return boundaries
def test_convert_diffpack(self): from dolfin import Mesh, MPI, MeshFunction, mpi_comm_world if MPI.size(mpi_comm_world()) != 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(len(mesh.domains().markers(3)), 48) self.assertEqual(len(mesh.domains().markers(2)), 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("size_t", mesh, mf_name) self.assertEqual(sum(mf.array() == marker), num) os.unlink(mf_name) # Clean up os.unlink(dfname)
def __init__(self, mesh_path=None): self.global_preprocessing_time = Stopwatch() self.local_preprocessing_time = Stopwatch() self.solving_time = Stopwatch() if mesh_path is not None: self.PATH = mesh_path logger.debug('Loading mesh...') # with XDMFFile(self.PATH + '.xdmf') as fh: # self._mesh = Mesh() # fh.read(self._mesh) # # with XDMFFile(self.PATH + '_boundaries.xdmf') as fh: # mvc = MeshValueCollection("size_t", self._mesh, 2) # fh.read(mvc, "boundaries") # self._boundaries = cpp.mesh.MeshFunctionSizet(self._mesh, mvc) # # with XDMFFile(self.PATH + '_subdomains.xdmf') as fh: # mvc = MeshValueCollection("size_t", self._mesh, 3) # fh.read(mvc, "subdomains") # self._subdomains = cpp.mesh.MeshFunctionSizet(self._mesh, mvc) self._mesh = Mesh(self.PATH + '.xml') self._subdomains = MeshFunction("size_t", self._mesh, self.PATH + '_physical_region.xml') self._boundaries = MeshFunction("size_t", self._mesh, self.PATH + '_facet_region.xml') logger.debug('Done.') self._degree = None
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 test_closed_boundary(advection_scheme): # FIXME: rk3 scheme does not bounces off the wall properly xmin, xmax = 0., 1. ymin, ymax = 0., 1. mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) # Particle x = np.array([[0.975, 0.475]]) # Given velocity field: vexpr = Constant((1., 0.)) # Given time do_step: dt = 0.05 # Then bounced position is x_bounced = np.array([[0.975, 0.475]]) p = particles(x, [x, x], mesh) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) # Different boundary parts bound_left = UnitSquareLeft() bound_right = UnitSquareRight() bound_top = UnitSquareTop() bound_bottom = UnitSquareBottom() # Mark all facets facet_marker = MeshFunction('size_t', mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # Mark as closed bound_right.mark(facet_marker, 1) # Mark other boundaries as open bound_left.mark(facet_marker, 2) bound_top.mark(facet_marker, 2) bound_bottom.mark(facet_marker, 2) if advection_scheme == 'euler': ap = advect_particles(p, V, v, facet_marker) elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, facet_marker) elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, facet_marker) else: assert False # Do one timestep, particle must bounce from wall of ap.do_step(dt) xpE = p.positions() # Check if particle correctly bounced off from closed wall xpE_root = comm.gather(xpE, root=0) if comm.rank == 0: xpE_root = np.float64(np.vstack(xpE_root)) error = np.linalg.norm(x_bounced - xpE_root) assert(error < 1e-10)
def dP(self, domain = "all"): """ Convenience wrapper for integral-point measure. If the mesh does not contain any cell domains, the measure for the whole mesh is returned. *Arguments* domain (:class:`string` / :class:`int`) name or ID of domain *Returns* :class:`dolfin:Measure` the measure """ if not self.mesh_has_domains(): return Measure('dP', self.mesh) if not self._dP.has_key(domain): v = TestFunction(self.FunctionSpace()) values = assemble(v*self.dx(domain)).array() # TODO improve this? markers = ((np.sign(np.ceil(values) - 0.5) + 1.0) / 2.0).astype(np.uint64) vertex_domains = MeshFunction('size_t', self.mesh, 0) vertex_domains.array()[:] = markers self._dP[domain] = Measure('dP', self.mesh)[vertex_domains](1) return self._dP[domain]
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 test_save_and_read_meshfunction_3D(tempdir): filename = os.path.join(tempdir, "meshfn-3d.h5") # Write to file mesh = UnitCubeMesh(MPI.comm_world, 2, 2, 2) mf_file = HDF5File(mesh.mpi_comm(), filename, "w") # save meshfuns to compare when reading back meshfunctions = [] for i in range(0, 4): mf = MeshFunction('double', mesh, i, 0.0) mp = cpp.mesh.midpoints(mesh, i, range(mesh.num_entities(i))) # NB choose a value to set which will be the same on every # process for each entity mf.values[:] = mp[:, 0] meshfunctions.append(mf) mf_file.write(mf, "/meshfunction/group/%d/meshfun" % i) mf_file.close() # Read back from file mf_file = HDF5File(mesh.mpi_comm(), filename, "r") for i in range(0, 4): mf2 = mf_file.read_mf_double(mesh, "/meshfunction/group/%d/meshfun" % i) assert numpy.all(meshfunctions[i].values == mf2.values) mf_file.close()
def test_save_3D_facet_function(tempdir, encoding, data_type): dtype_str, dtype = data_type mesh = UnitCubeMesh(MPI.comm_world, 4, 4, 4) mf = MeshFunction(dtype_str, mesh, mesh.topology.dim - 1, 0) mf.rename("facets") if (MPI.size(mesh.mpi_comm()) == 1): for facet in Facets(mesh): mf[facet] = dtype(facet.index()) else: for facet in Facets(mesh): mf[facet] = dtype(facet.global_index()) filename = os.path.join(tempdir, "mf_facet_3D_%s.xdmf" % dtype_str) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as xdmf: xdmf.write(mf) with XDMFFile(mesh.mpi_comm(), filename) as xdmf: read_function = getattr(xdmf, "read_mf_" + dtype_str) mf_in = read_function(mesh, "facets") diff = 0 for facet in Facets(mesh): diff += (mf_in[facet] - mf[facet]) assert diff == 0
def create(mesh, domain_ids, invert=False): """ Creates a wrapped mesh from a super mesh for a given collection of domain IDs. *Arguments* mesh (:class:`dolfin.Mesh`) The mesh. domain_ids (:class:`[int]`) List of domain IDs invert (:class:`bool`) Invert list of domain IDs *Returns* :class:`WrappedMesh` The wrapped mesh """ if invert or isinstance(domain_ids, list) or isinstance(domain_ids, tuple): if isinstance(domain_ids, int): domain_ids = (domain_ids,) subdomains = MeshFunction('size_t', mesh, 3, mesh.domains()) combined_subdomains = CellFunction("size_t", mesh, 0) for domain_id in domain_ids: combined_subdomains.array()[subdomains.array() == domain_id] = 1 submesh = SubMesh(mesh, combined_subdomains, 0 if invert else 1) else: submesh = SubMesh(mesh, domain_ids) submesh.__class__ = WrappedMesh submesh._init(mesh) return submesh
def __init__(self, U_m, mesh): """Function spaces and BCs""" V = VectorFunctionSpace(mesh, 'P', 2) Q = FunctionSpace(mesh, 'P', 1) self.mesh = mesh self.vu, self.vp = TestFunction(V), TestFunction(Q) # for integration self.u_, self.p_ = Function(V), Function(Q) # for the solution self.u_1, self.p_1 = Function(V), Function(Q) # for the prev. solution self.u_k, self.p_k = Function(V), Function(Q) # for the prev. solution self.u, self.p = TrialFunction(V), TrialFunction(Q) # unknown! U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)" x = [0, .41 / 2] # evaluate the Expression at the center of the channel self.U_mean = np.mean(2 / 3 * eval(U0_str)) U0 = Expression((U0_str, "0"), U_m=U_m, degree=2) bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall) bc1 = DirichletBC(V, Constant((0, 0)), topandbottom) bc2 = DirichletBC(V, U0, inlet) bc3 = DirichletBC(Q, Constant(0), outlet) self.bcu = [bc0, bc1, bc2] self.bcp = [bc3] # ds is needed to compute drag and lift. ASD1 = AutoSubDomain(topandbottom) ASD2 = AutoSubDomain(cylinderwall) mf = MeshFunction("size_t", mesh, 1) mf.set_all(0) ASD1.mark(mf, 1) ASD2.mark(mf, 2) self.ds_ = ds(subdomain_data=mf, domain=mesh) return
def test_save_mesh_value_collection(tempdir, encoding, data_type): dtype_str, dtype = data_type mesh = UnitCubeMesh(MPI.comm_world, 4, 4, 4) tdim = mesh.topology.dim meshfn = MeshFunction(dtype_str, mesh, mesh.topology.dim, False) meshfn.rename("volume_marker") for c in Cells(mesh): if c.midpoint()[1] > 0.1: meshfn[c] = dtype(1) if c.midpoint()[1] > 0.9: meshfn[c] = dtype(2) for mvc_dim in range(0, tdim + 1): mvc = MeshValueCollection(dtype_str, mesh, mvc_dim) tag = "dim_%d_marker" % mvc_dim mvc.rename(tag) mesh.init(mvc_dim, tdim) for e in MeshEntities(mesh, mvc_dim): if (e.midpoint()[0] > 0.5): mvc.set_value(e.index(), dtype(1)) filename = os.path.join(tempdir, "mvc_%d.xdmf" % mvc_dim) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as xdmf: xdmf.write(meshfn) xdmf.write(mvc) with XDMFFile(mesh.mpi_comm(), filename) as xdmf: read_function = getattr(xdmf, "read_mvc_" + dtype_str) mvc = read_function(mesh, tag)
def test_save_2D_facet_function(tempdir, encoding, data_type): if invalid_config(encoding): pytest.skip("XDMF unsupported in current configuration") dtype_str, dtype = data_type mesh = UnitSquareMesh(MPI.comm_world, 32, 32) mf = MeshFunction(dtype_str, mesh, mesh.topology.dim - 1, 0) mf.rename("facets") if (MPI.size(mesh.mpi_comm()) == 1): for facet in Facets(mesh): mf[facet] = dtype(facet.index()) else: for facet in Facets(mesh): mf[facet] = dtype(facet.global_index()) filename = os.path.join(tempdir, "mf_facet_2D_%s.xdmf" % dtype_str) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as xdmf: xdmf.write(mf) with XDMFFile(mesh.mpi_comm(), filename) as xdmf: read_function = getattr(xdmf, "read_mf_" + dtype_str) mf_in = read_function(mesh, "facets") diff = 0 for facet in Facets(mesh): diff += (mf_in[facet] - mf[facet]) assert diff == 0
def test_save_3D_cell_function(tempdir, encoding, data_type): if invalid_config(encoding): pytest.skip("XDMF unsupported in current configuration") dtype_str, dtype = data_type mesh = UnitCubeMesh(MPI.comm_world, 4, 4, 4) mf = MeshFunction(dtype_str, mesh, mesh.topology.dim, 0) mf.rename("cells") for cell in Cells(mesh): mf[cell] = dtype(cell.index()) filename = os.path.join(tempdir, "mf_3D_%s.xdmf" % dtype_str) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(mf) # mf_in = MeshFunction(dtype_str, mesh, mesh.topology.dim, 0) with XDMFFile(mesh.mpi_comm(), filename) as xdmf: read_function = getattr(xdmf, "read_mf_" + dtype_str) mf_in = read_function(mesh, "cells") diff = 0 for cell in Cells(mesh): diff += (mf_in[cell] - mf[cell]) assert diff == 0
def test_mesh_function_assign_2D_cells(): mesh = UnitSquareMesh(MPI.comm_world, 3, 3) ncells = mesh.num_cells() f = MeshFunction("int", mesh, mesh.topology.dim, 0) for c in range(ncells): f.values[c] = ncells - c g = MeshValueCollection("int", mesh, 2) g.assign(f) assert ncells == len(f.values) assert ncells == g.size() f2 = MeshFunction("int", mesh, g, 0) for c in range(mesh.num_cells()): value = ncells - c assert value == g.get_value(c, 0) assert f2.values[c] == g.get_value(c, 0) h = MeshValueCollection("int", mesh, 2) global_indices = mesh.topology.global_indices(2) ncells_global = mesh.num_entities_global(2) for c in range(mesh.num_cells()): if global_indices[c] in [5, 8, 10]: continue value = ncells_global - global_indices[c] h.set_value(c, int(value)) f3 = MeshFunction("int", mesh, h, 0) values = f3.values values[values > ncells_global] = 0. assert MPI.sum(mesh.mpi_comm(), values.sum() * 1.0) == 140.
def mplot_cellfunction( cell_function: df.MeshFunction) -> Tuple[plt.Figure, Any]: """Return a pseudocolor plot of an unstructured triangular grid.""" fig, ax = plt.subplots(1) tri = mesh2triang(cell_function.mesh()) ax.tripcolor(tri, facecolors=cell_function.array()) return fig, ax
def test_convert_diffpack_2d(self): from dolfin import Mesh, MPI, MeshFunction 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 test_mesh_function_assign_2D_facets(): mesh = UnitSquareMesh(MPI.comm_world, 3, 3) mesh.create_entities(1) tdim = mesh.topology.dim num_cell_facets = cpp.mesh.cell_num_entities(mesh.cell_type, tdim - 1) f = MeshFunction("int", mesh, tdim - 1, 25) connectivity = mesh.topology.connectivity(tdim, tdim - 1) for c in range(mesh.num_cells()): facets = connectivity.connections(c) for i in range(num_cell_facets): assert 25 == f.values[facets[i]] g = MeshValueCollection("int", mesh, 1) g.assign(f) assert mesh.num_entities(tdim - 1) == len(f.values) assert mesh.num_cells() * 3 == g.size() for c in range(mesh.num_cells()): for i in range(num_cell_facets): assert 25 == g.get_value(c, i) f2 = MeshFunction("int", mesh, g, 0) connectivity = mesh.topology.connectivity(tdim, tdim - 1) for c in range(mesh.num_cells()): facets = connectivity.connections(c) for i in range(num_cell_facets): assert f2.values[facets[i]] == g.get_value(c, i)
def transfer_markers(mesh, f, markers=None): ''' Let mesh be a mesh embedded into mesh(f). Transfer all markers from f to the mesh. ''' # Check that we are embdded parent_mesh = f.mesh() assert parent_mesh.id() in mesh.parent_entity_map # If we are embedded then the transfer is only possible of the lower # dimensional entities assert f.dim() < mesh.topology().dim() cdim = mesh.topology().dim() edim = f.dim() # That of entities # All not zeros if markers is None: markers = set(f.array()) - set((0, )) # The idea is to look up mesh.entities in parent by vertex ids child_parent_vertex = mesh.parent_entity_map[parent_mesh.id()][0] child_parent_cell = mesh.parent_entity_map[parent_mesh.id()][cdim] # child_entity -> as vertex in child -> as vertex in parent # \- connected child cells -> parent -> cells -> parent cell entities as vertex # Entity in terms of vertices mesh.init(edim, 0) ch_e2v = mesh.topology()(edim, 0) # The connected cell; we already have child to parent for cell mesh.init(edim, cdim) ch_e2c = mesh.topology()(edim, cdim) # Then parent entities parent_mesh.init(cdim, edim) p_c2e = parent_mesh.topology()(cdim, edim) # In terms of vertices parent_mesh.init(edim, 0) p_e2v = parent_mesh.topology()(edim, 0) child_f = MeshFunction('size_t', mesh, edim, 0) ch_values = child_f.array() # Assignee p_values = f.array() for entity in range(len(ch_values)): # As vertices in parent e_as_vertex = set(child_parent_vertex[v] for v in ch_e2v(entity)) ch_cells = iter(ch_e2c(entity)) # One of the cells entities should match for ch_cell in ch_cells: for p_entity in p_c2e(child_parent_cell[ch_cell]): found = p_values[p_entity] in markers and set(p_e2v(p_entity)) == e_as_vertex # Can assign color if found: break if found: ch_values[entity] = p_values[p_entity] break return child_f
def test_save_3D_vertex_function(tempdir, encoding, data_type): dtype_str, dtype = data_type filename = os.path.join(tempdir, "mf_vertex_3D_%s.xdmf" % dtype_str) mesh = UnitCubeMesh(MPI.comm_world, 4, 4, 4) mf = MeshFunction(dtype_str, mesh, 0, 0) mf.values[:] = numpy.arange(mesh.num_entities(0), dtype=dtype) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(mf)
def refine_meshes(self, subdomain): sub1_marker = MeshFunction("bool", self.mesh1, self.mesh1.topology().dim()) sub2_marker = MeshFunction("bool", self.mesh2, self.mesh2.topology().dim()) subdomain.mark(sub1_marker, True) subdomain.mark(sub2_marker, True) self.mesh1 = refine(self.mesh1, sub1_marker) self.mesh2 = refine(self.mesh2, sub2_marker)
def test_open_boundary(advection_scheme): xmin, xmax = 0.0, 1.0 ymin, ymax = 0.0, 1.0 pres = 3 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) # Particle x = RandomRectangle(Point(0.955, 0.45), Point(1.0, 0.55)).generate([pres, pres]) x = comm.bcast(x, root=0) # Given velocity field: vexpr = Constant((1.0, 1.0)) # Given time do_step: dt = 0.05 p = particles(x, [x, x], mesh) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) # Different boundary parts bound_left = UnitSquareLeft() bound_right = UnitSquareRight() bound_top = UnitSquareTop() bound_bottom = UnitSquareBottom() # Mark all facets facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # Mark as open bound_right.mark(facet_marker, 2) # Mark other boundaries as closed bound_left.mark(facet_marker, 1) bound_top.mark(facet_marker, 1) bound_bottom.mark(facet_marker, 1) if advection_scheme == "euler": ap = advect_particles(p, V, v, facet_marker) elif advection_scheme == "rk2": ap = advect_rk2(p, V, v, facet_marker) elif advection_scheme == "rk3": ap = advect_rk3(p, V, v, facet_marker) else: assert False # Do one timestep, particle must bounce from wall of ap.do_step(dt) num_particles = p.number_of_particles() # Check if all particles left domain if comm.rank == 0: assert (num_particles == 0)
def read_mesh(): # mesh = Mesh("data/backward_facing_step.xml") # subdomains = MeshFunction("size_t", mesh, "data/backward_facing_step_physical_region.xml") # boundaries = MeshFunction("size_t", mesh, "data/backward_facing_step_facet_region.xml") mesh = Mesh("data/hyperelastic_cube.xml") subdomains = MeshFunction("size_t", mesh, "data/hyperelastic_cube_physical_region.xml") boundaries = MeshFunction("size_t", mesh, "data/hyperelastic_cube_facet_region.xml") restrictions = MeshRestriction(mesh, "data/hyperelastic_cube_interface_restriction.rtc.xml") return (mesh, subdomains, boundaries, restrictions)
def _test_eigen_solver_sparse(callback_type): from rbnics.backends.dolfin import EigenSolver # Define mesh mesh = UnitSquareMesh(10, 10) # Define function space V_element = VectorElement("Lagrange", mesh.ufl_cell(), 2) Q_element = FiniteElement("Lagrange", mesh.ufl_cell(), 1) W_element = MixedElement(V_element, Q_element) W = FunctionSpace(mesh, W_element) # Create boundaries class Wall(SubDomain): def inside(self, x, on_boundary): return on_boundary and (x[1] < 0 + DOLFIN_EPS or x[1] > 1 - DOLFIN_EPS) boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundaries.set_all(0) wall = Wall() wall.mark(boundaries, 1) # Define variational problem vq = TestFunction(W) (v, q) = split(vq) up = TrialFunction(W) (u, p) = split(up) lhs = inner(grad(u), grad(v)) * dx - div(v) * p * dx - div(u) * q * dx rhs = -inner(p, q) * dx # Define boundary condition bc = [DirichletBC(W.sub(0), Constant((0., 0.)), boundaries, 1)] # Define eigensolver depending on callback type assert callback_type in ("form callbacks", "tensor callbacks") if callback_type == "form callbacks": solver = EigenSolver(W, lhs, rhs, bc) elif callback_type == "tensor callbacks": LHS = assemble(lhs) RHS = assemble(rhs) solver = EigenSolver(W, LHS, RHS, bc) # Solve the eigenproblem solver.set_parameters({ "linear_solver": "mumps", "problem_type": "gen_non_hermitian", "spectrum": "target real", "spectral_transform": "shift-and-invert", "spectral_shift": 1.e-5 }) solver.solve(1) r, c = solver.get_eigenvalue(0) assert abs(c) < 1.e-10 assert r > 0., "r = " + str(r) + " is not positive" print("Sparse inf-sup constant: ", sqrt(r)) return (sqrt(r), solver.condensed_A, solver.condensed_B)
def convert_meshfunctions_to_submesh(mesh, submesh, meshfunctions_on_mesh): assert meshfunctions_on_mesh is None or (isinstance( meshfunctions_on_mesh, list) and len(meshfunctions_on_mesh) > 0) if meshfunctions_on_mesh is None: return None meshfunctions_on_submesh = list() # Create submesh subdomains for mesh_subdomain in meshfunctions_on_mesh: submesh_subdomain = MeshFunction("size_t", submesh, mesh_subdomain.dim()) submesh_subdomain.set_all(0) assert submesh_subdomain.dim() in (submesh.topology().dim(), submesh.topology().dim() - 1) if submesh_subdomain.dim() == submesh.topology().dim(): for submesh_cell in cells(submesh): submesh_subdomain.array()[ submesh_cell.index()] = mesh_subdomain.array()[ submesh.submesh_to_mesh_cell_local_indices[ submesh_cell.index()]] elif submesh_subdomain.dim() == submesh.topology().dim() - 1: for submesh_facet in facets(submesh): submesh_subdomain.array()[ submesh_facet.index()] = mesh_subdomain.array()[ submesh.submesh_to_mesh_facet_local_indices[ submesh_facet.index()]] else: # impossible to arrive here anyway, thanks to the assert raise TypeError( "Invalid arguments in convert_meshfunctions_to_submesh.") meshfunctions_on_submesh.append(submesh_subdomain) return meshfunctions_on_submesh
def test_save_3D_edge_function(tempdir, encoding, data_type): dtype_str, dtype = data_type mesh = UnitCubeMesh(MPI.comm_world, 4, 4, 4) mf = MeshFunction(dtype_str, mesh, 1, 0) mf.rename("edges") for edge in Edges(mesh): mf[edge] = dtype(edge.index()) filename = os.path.join(tempdir, "mf_edge_3D_%s.xdmf" % dtype_str) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(mf)
def test_advect_periodic_facet_marker(advection_scheme): xmin, xmax = 0.0, 1.0 ymin, ymax = 0.0, 1.0 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) boundaries = Boundaries() boundaries.mark(facet_marker, 3) lims = np.array([ [xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax], [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax], ]) vexpr = Constant((1.0, 1.0)) V = VectorFunctionSpace(mesh, "CG", 1) x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([3, 3]) x = comm.bcast(x, root=0) dt = 0.05 v = Function(V) v.assign(vexpr) p = particles(x, [x * 0, x**2], mesh) if advection_scheme == "euler": ap = advect_particles(p, V, v, facet_marker, lims.flatten()) elif advection_scheme == "rk2": ap = advect_rk2(p, V, v, facet_marker, lims.flatten()) elif advection_scheme == "rk3": ap = advect_rk3(p, V, v, facet_marker, lims.flatten()) else: assert False xp0 = p.positions() t = 0.0 while t < 1.0 - 1e-12: ap.do_step(dt) t += dt xpE = p.positions() # Check if position correct xp0_root = comm.gather(xp0, root=0) xpE_root = comm.gather(xpE, root=0) if comm.Get_rank() == 0: xp0_root = np.float32(np.vstack(xp0_root)) xpE_root = np.float32(np.vstack(xpE_root)) error = np.linalg.norm(xp0_root - xpE_root) assert error < 1e-10
def read_h5(h5Path): mesh = Mesh() hdf = HDF5File(mesh.mpi_comm(), h5Path, 'r') hdf.read(mesh, '/mesh', False) subdomains = MeshFunction('size_t', mesh, 3) boundaries = MeshFunction('size_t', mesh, 2) hdf.read(subdomains, '/subdomains') hdf.read(boundaries, '/boundaries') return mesh, subdomains, boundaries
def __init__(self, n=16, divide=1, threshold=12.3, left_side_num=3, left_side_denom=4): """ Store parameters, initialize data exports (latex, txt). """ # left_side_num/denom are either height, assuming base is 1, # or left and bottom side lengths self.n = n self.threshold = threshold / left_side_denom ** 2 self.left_side = [0] * (n + 1) self.bottom_side = [0] * (n + 1) self.left_side_len = left_side_num * 1.0 / left_side_denom self.left_side_num = left_side_num self.left_side_denom = left_side_denom self.folder = "results" self.name = "domains_{}_{}_{}".format(n, divide, threshold) self.filename = self.folder + "/" + self.name + ".tex" self.matrixZname = self.folder + "/matrices_Z/" + self.name self.matrixQname = self.folder + "/matrices_Q/" + self.name self.genericname = self.folder + "/" + self.name self.textname = self.folder + "/" + self.name + ".txt" f = open(self.textname, 'w') f.close() self.latex = "cd " + self.folder + "; pdflatex --interaction=batchmode" \ + " {0}.tex; rm {0}.aux {0}.log".format(self.name) self.shift = 0 # common mesh, ready to cut/apply Dirichlet BC self.mesh = Triangle(self.left_side_num, left_side_denom) while self.mesh.size(2) < self.n * self.n: self.mesh = refine(self.mesh) for i in range(divide): self.mesh = refine(self.mesh) boundary = MeshFunction("size_t", self.mesh, 1) boundary.set_all(0) self.plotted = plot( boundary, prefix='animation/animation', scalarbar=False, window_width=1024, window_height=1024) print 'Grid size: ', self.n ** 2 print 'Mesh size: ', self.mesh.size(2) # setup solver self.solver = Solver(self.mesh, left_side_num, left_side_denom) self.mass = self.solver.B self.stiff = self.solver.A print np.unique(self.stiff.data) self.save_matrices(0) # save dofs f = open(self.genericname+'_dofmap.txt', 'w') for vec in self.solver.dofs: print >>f, vec f.close()
def square_with_obstacle(): # Create classes for defining parts of the boundaries and the interior # of the domain class Left(SubDomain): def inside(self, x, on_boundary): return near(x[0], 0.0) class Right(SubDomain): def inside(self, x, on_boundary): return near(x[0], 1.0) class Bottom(SubDomain): def inside(self, x, on_boundary): return near(x[1], 0.0) class Top(SubDomain): def inside(self, x, on_boundary): return near(x[1], 1.0) class Obstacle(SubDomain): def inside(self, x, on_boundary): return between(x[1], (0.5, 0.7)) and between(x[0], (0.2, 1.0)) # Initialize sub-domain instances left = Left() top = Top() right = Right() bottom = Bottom() obstacle = Obstacle() # Define mesh mesh = UnitSquareMesh(100, 100, "crossed") # Initialize mesh function for interior domains domains = CellFunction("size_t", mesh) domains.set_all(0) obstacle.mark(domains, 1) # Initialize mesh function for boundary domains boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundaries.set_all(0) left.mark(boundaries, 1) top.mark(boundaries, 2) right.mark(boundaries, 3) bottom.mark(boundaries, 4) boundary_indices = {"left": 1, "top": 2, "right": 3, "bottom": 4} f = Constant(0.0) theta0 = Constant(293.0) return mesh, f, boundaries, boundary_indices, theta0
def derived_bcs(V, original_bcs, u_): new_bcs = [] # Check first if user has declared subdomains subdomain = original_bcs[0].user_sub_domain() if subdomain is None: mesh = V.mesh() ff = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0) for i, bc in enumerate(original_bcs): bc.apply(u_[0].vector()) # Need to initialize bc m = bc.markers() # Get facet indices of boundary ff.array()[m] = i + 1 new_bcs.append(DirichletBC(V, Constant(0), ff, i + 1)) else: for i, bc in enumerate(original_bcs): subdomain = bc.user_sub_domain() new_bcs.append(DirichletBC(V, Constant(0), subdomain)) return new_bcs
def test_ale(): # Create some mesh mesh = UnitSquareMesh(4, 5) # Make some cell function # FIXME: Initialization by array indexing is probably # not a good way for parallel test cellfunc = MeshFunction('size_t', mesh, mesh.topology().dim()) cellfunc.array()[0:4] = 0 cellfunc.array()[4:] = 1 # Create submeshes - this does not work in parallel submesh0 = SubMesh(mesh, cellfunc, 0) submesh1 = SubMesh(mesh, cellfunc, 1) # Move submesh0 disp = Constant(("0.1", "-0.1")) ALE.move(submesh0, disp) # Move and smooth submesh1 accordignly ALE.move(submesh1, submesh0) # Move mesh accordingly parent_vertex_indices_0 = \ submesh0.data().array('parent_vertex_indices', 0) parent_vertex_indices_1 = \ submesh1.data().array('parent_vertex_indices', 0) mesh.coordinates()[parent_vertex_indices_0[:]] = \ submesh0.coordinates()[:] mesh.coordinates()[parent_vertex_indices_1[:]] = \ submesh1.coordinates()[:] # If test passes here then it is probably working # Check for cell quality for sure magic_number = 0.28 rmin = MeshQuality.radius_ratio_min_max(mesh)[0] assert rmin > magic_number
def __init__(self, mesh, num, denom, method="CR"): """ Assemble matrices and cache matrices. """ self.V = FunctionSpace(mesh, method, 1) # save coordinates of DOFs self.dofs = np.reshape(self.V.dofmap().tabulate_all_coordinates(mesh), (-1, 2)) u = TrialFunction(self.V) v = TestFunction(self.V) self.boundary = MeshFunction("size_t", mesh, 1) # assemble matrices a = inner(grad(u), grad(v)) * dx b = u * v * dx self.A = uBLASSparseMatrix() self.A = assemble(a, tensor=self.A) self.A.compress() self.B = uBLASSparseMatrix() self.B = assemble(b, tensor=self.B) self.B.compress() size = mesh.size(2) # cell diameter calculation self.H2 = (num ** 2 + denom ** 2) * 1.0 / size # print "Theoretical cell diameter: ", sqrt(self.H2) # print "FEniCS calculated: ", mesh.hmax() # Matrices have rational entries. We can rescale to get integers # and save as scipy matrices scaleB = 6.0*size/num/denom self.scaleB = scaleB self.B *= scaleB r, c, val = self.B.data() val = np.round(val) self.B = sps.csr_matrix((val, c, r)) # check if B is diagonal assert len(self.B.diagonal()) == self.B.nnz # find B inverse self.Binv = sps.csr_matrix((1.0/val, c, r)) scaleA = 1.0*num*denom/2 self.scaleA = scaleA self.A *= scaleA r, c, val = self.A.data() self.A = sps.csr_matrix((np.round(val), c, r)) self.scale = scaleA/scaleB print 'scaling A by: ', scaleA print 'scaling B by: ', scaleB print 'eigenvalues scale by:', self.scale
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 les_setup(u_, mesh, assemble_matrix, CG1Function, nut_krylov_solver, bcs, **NS_namespace): """ Set up for solving the Germano Dynamic LES model applying Lagrangian Averaging. """ # Create function spaces CG1 = FunctionSpace(mesh, "CG", 1) p, q = TrialFunction(CG1), TestFunction(CG1) dim = mesh.geometry().dim() # Define delta and project delta**2 to CG1 delta = pow(CellVolume(mesh), 1. / dim) delta_CG1_sq = project(delta, CG1) delta_CG1_sq.vector().set_local(delta_CG1_sq.vector().array()**2) delta_CG1_sq.vector().apply("insert") # Define nut_ Sij = sym(grad(u_)) magS = sqrt(2 * inner(Sij, Sij)) Cs = Function(CG1) nut_form = Cs**2 * delta**2 * magS # Create nut_ BCs ff = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0) bcs_nut = [] for i, bc in enumerate(bcs['u0']): bc.apply(u_[0].vector()) # Need to initialize bc m = bc.markers() # Get facet indices of boundary ff.array()[m] = i + 1 bcs_nut.append(DirichletBC(CG1, Constant(0), ff, i + 1)) nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, bounded=True, name="nut") # Create functions for holding the different velocities u_CG1 = as_vector([Function(CG1) for i in range(dim)]) u_filtered = as_vector([Function(CG1) for i in range(dim)]) dummy = Function(CG1) ll = LagrangeInterpolator() # Assemble required filter matrices and functions G_under = Function(CG1, assemble(TestFunction(CG1) * dx)) G_under.vector().set_local(1. / G_under.vector().array()) G_under.vector().apply("insert") G_matr = assemble(inner(p, q) * dx) # Set up functions for Lij and Mij Lij = [Function(CG1) for i in range(dim * dim)] Mij = [Function(CG1) for i in range(dim * dim)] # Check if case is 2D or 3D and set up uiuj product pairs and # Sij forms, assemble required matrices Sijcomps = [Function(CG1) for i in range(dim * dim)] Sijfcomps = [Function(CG1) for i in range(dim * dim)] # Assemble some required matrices for solving for rate of strain terms Sijmats = [assemble_matrix(p.dx(i) * q * dx) for i in range(dim)] if dim == 3: tensdim = 6 uiuj_pairs = ((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)) else: tensdim = 3 uiuj_pairs = ((0, 0), (0, 1), (1, 1)) # Set up Lagrange functions JLM = Function(CG1) JLM.vector()[:] += 1E-32 JMM = Function(CG1) JMM.vector()[:] += 1 return dict(Sij=Sij, nut_form=nut_form, nut_=nut_, delta=delta, bcs_nut=bcs_nut, delta_CG1_sq=delta_CG1_sq, CG1=CG1, Cs=Cs, u_CG1=u_CG1, u_filtered=u_filtered, ll=ll, Lij=Lij, Mij=Mij, Sijcomps=Sijcomps, Sijfcomps=Sijfcomps, Sijmats=Sijmats, JLM=JLM, JMM=JMM, dim=dim, tensdim=tensdim, G_matr=G_matr, G_under=G_under, dummy=dummy, uiuj_pairs=uiuj_pairs)
def femsolve(): ''' Bilineaarinen muoto: a(u,v) = L(v) a(u,v) = (inner(grad(u), grad(v)) + u*v)*dx L(v) = f*v*dx - g*v*ds g(x) = -du/dx = -u1, x = x1 u(x0) = u0 Omega = {xeR|x0<=x<=x1} ''' from dolfin import UnitInterval, FunctionSpace, DirichletBC, TrialFunction from dolfin import TestFunction, grad, Constant, Function, solve, inner, dx, ds from dolfin import MeshFunction, assemble import dolfin # from dolfin import set_log_level, PROCESS # Create mesh and define function space mesh = UnitInterval(30) V = FunctionSpace(mesh, 'Lagrange', 2) boundaries = MeshFunction('uint', mesh, mesh.topology().dim()-1) boundaries.set_all(0) class Left(dolfin.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 # tolerance for coordinate comparisons return on_boundary and abs(x[0]) < tol class Right(dolfin.SubDomain): def inside(self, x, on_boundary): return dolfin.near(x[0], 1.0) left = Left() right = Right() left.mark(boundaries, 1) right.mark(boundaries, 2) # def u0_boundary(x): # return abs(x[0]) < tol # # bc = DirichletBC(V, Constant(u0), lambda x: abs(x[0]) < tol) bcs = [DirichletBC(V, Constant(u0), boundaries, 1)] # Define variational problem u = TrialFunction(V) v = TestFunction(V) a = (inner(grad(u), grad(v)) + u*v)*dx g = Constant(-u1) L = Constant(f)*v*dx - g*v*ds(2) # set_log_level(PROCESS) # Compute solution A = assemble(a, exterior_facet_domains=boundaries) b = assemble(L, exterior_facet_domains=boundaries) for bc in bcs: bc.apply(A, b) u = Function(V) solve(A, u.vector(), b, 'lu') coor = mesh.coordinates() u_array = u.vector().array() a = [] b = [] for i in range(mesh.num_vertices()): a.append(coor[i]) b.append(u_array[i]) print('u(%3.2f) = %0.14E'%(coor[i],u_array[i])) import numpy as np np.savez('fem',a,b)
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)
class Solver(object): """ First order FEM with CR elements. Nonconforming CR elements give lower bounds for eigenvalues after apropriate postprocessing is applied. """ def __init__(self, mesh, num, denom, method="CR"): """ Assemble matrices and cache matrices. """ self.V = FunctionSpace(mesh, method, 1) # save coordinates of DOFs self.dofs = np.reshape(self.V.dofmap().tabulate_all_coordinates(mesh), (-1, 2)) u = TrialFunction(self.V) v = TestFunction(self.V) self.boundary = MeshFunction("size_t", mesh, 1) # assemble matrices a = inner(grad(u), grad(v)) * dx b = u * v * dx self.A = uBLASSparseMatrix() self.A = assemble(a, tensor=self.A) self.A.compress() self.B = uBLASSparseMatrix() self.B = assemble(b, tensor=self.B) self.B.compress() size = mesh.size(2) # cell diameter calculation self.H2 = (num ** 2 + denom ** 2) * 1.0 / size # print "Theoretical cell diameter: ", sqrt(self.H2) # print "FEniCS calculated: ", mesh.hmax() # Matrices have rational entries. We can rescale to get integers # and save as scipy matrices scaleB = 6.0*size/num/denom self.scaleB = scaleB self.B *= scaleB r, c, val = self.B.data() val = np.round(val) self.B = sps.csr_matrix((val, c, r)) # check if B is diagonal assert len(self.B.diagonal()) == self.B.nnz # find B inverse self.Binv = sps.csr_matrix((1.0/val, c, r)) scaleA = 1.0*num*denom/2 self.scaleA = scaleA self.A *= scaleA r, c, val = self.A.data() self.A = sps.csr_matrix((np.round(val), c, r)) self.scale = scaleA/scaleB print 'scaling A by: ', scaleA print 'scaling B by: ', scaleB print 'eigenvalues scale by:', self.scale def solve(self, dirichlet=lambda x: False, plotted=None): """ Find eigenvalues given a boundary condition function. dirichlet is a function returning True if x is on Dirichlet BC. """ self.boundary.set_all(0) d = Dirichlet() d.init(dirichlet) d.mark(self.boundary, 1) if plotted is not None: plotted.plot(self.boundary) # plotted.write_png() # indices for non-Dirichlet rows/columns indices = np.nonzero(np.apply_along_axis( lambda x: not dirichlet(x), 1, self.dofs))[0] # remove Dirichlet rows and columns from A self.AA = (self.A[indices, :]).tocsc()[:, indices] # remove Dirichlet rows and columns from B self.BB = (self.B[indices, :]).tocsc()[:, indices] self.BBinv = (self.Binv[indices, :]).tocsc()[:, indices] # solve using scipy eigs, eigfs = ssl.eigsh(self.AA, k=2, M=self.BB, sigma=0, which='LM') self.raweigs = [eigs[0], eigs[1]] eig = eigs[0] # turn eigf into a function eigf = np.array(eigfs[:, 0]).flatten() # we were solving only for some dofs, rest is 0 # u = Function(self.V) # u.vector()[:] = 0 # u.vector()[indices] = eigf # find algebraic residual # both L2 norm of u and B norm of eigf should equal 1 # print assemble(u*u*dx), self.BB.dot(eigf).dot(eigf) res = self.AA.dot(eigf) - eig * self.BB.dot(eigf) resnorm = np.sqrt(self.BBinv.dot(res).dot(res)) self.residual = [resnorm, 0] # apply Carstensen-Gedicke transformations to eig # # kappa^2 less than 0.1932 eig = (eig - resnorm) / (1 + 0.1932 * (eig - resnorm) * self.H2 / self.scale) # scale back the eigenvalue eig = eig/self.scale # find residual for the second eigenvalue (for gap calculations) eigf = np.array(eigfs[:, 1]).flatten() res = self.AA.dot(eigf) - eigs[1] * self.BB.dot(eigf) resnorm = np.sqrt(self.BBinv.dot(res).dot(res)) self.residual[1] = resnorm # return (eig, u) # pair (eigenvalue,eigenfunctions) return (eig, None) # pair (eigenvalue,eigenfunctions)
def peter(): base = "../meshes/2d/peter" # base = '../meshes/2d/peter-fine' mesh = Mesh(base + ".xml") subdomains = MeshFunction("size_t", mesh, base + "_physical_region.xml") workpiece_index = 3 subdomain_materials = {1: "SiC", 2: "carbon steel", 3: "GaAs (liquid)"} submesh_workpiece = SubMesh(mesh, subdomains, workpiece_index) W = VectorFunctionSpace(submesh_workpiece, "CG", 2) Q = FunctionSpace(submesh_workpiece, "CG", 2) # Define melt boundaries. class LeftBoundary(SubDomain): def inside(self, x, on_boundary): # Be especially careful in the corners when defining the r=0 axis: # For the PPE to be consistent, we need to have n.u=0 *everywhere* # on the non-(r=0) boundaries. return ( on_boundary and x[0] < GMSH_EPS and 0.005 + GMSH_EPS < x[1] and x[1] < 0.050 - GMSH_EPS ) class SurfaceBoundary(SubDomain): def inside(self, x, on_boundary): return ( on_boundary and 0.055 - GMSH_EPS < x[1] and 0.030 - GMSH_EPS < x[0] and x[0] < 0.075 + GMSH_EPS ) class StampBoundary(SubDomain): def inside(self, x, on_boundary): # Well well. If we don't include the endpoints here, the PPE turns # out inconsistent. This is weird since the endpoints should be # picked up by RightBoundary and StampBoundary. return ( on_boundary and 0.050 - GMSH_EPS < x[1] and x[1] < 0.055 + GMSH_EPS and x[0] < 0.030 + GMSH_EPS ) class LowerBoundary(SubDomain): def inside(self, x, on_boundary): # Danger, danger. # If the rightmost point (0.075, 0.010) is excluded, the PPE will # end up inconsistent. # This is actually weird since it should be picked up by # RightBoundary. return on_boundary and ( x[1] < 0.005 + GMSH_EPS or (x[0] > 0.070 - GMSH_EPS and x[1] < 0.010 + GMSH_EPS) ) class RightBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] > 0.075 - GMSH_EPS left_boundary = LeftBoundary() lower_boundary = LowerBoundary() right_boundary = RightBoundary() surface_boundary = SurfaceBoundary() stamp_boundary = StampBoundary() # Define workpiece boundaries. wp_boundaries = MeshFunction( "size_t", submesh_workpiece, self.submesh_workpiece.topology().dim() - 1 ) wp_boundaries.set_all(0) left_boundary.mark(wp_boundaries, 1) lower_boundary.mark(wp_boundaries, 2) right_boundary.mark(wp_boundaries, 3) surface_boundary.mark(wp_boundaries, 4) stamp_boundary.mark(wp_boundaries, 5) # For local use only: wp_boundary_indices = {"left": 1, "lower": 2, "right": 3, "surface": 4, "stamp": 5} # Boundary conditions for the velocity. u_bcs = [ DirichletBC(W, (0.0, 0.0), stamp_boundary), DirichletBC(W, (0.0, 0.0), right_boundary), DirichletBC(W, (0.0, 0.0), lower_boundary), DirichletBC(W.sub(0), 0.0, left_boundary), DirichletBC(W.sub(1), 0.0, surface_boundary), ] p_bcs = [] # Boundary conditions for the heat equation. # Dirichlet theta_bcs_d = [] # Neumann theta_bcs_n = {} # Robin, i.e., # # -dtheta/dn = alpha (theta - theta0) # # (with alpha>0 to preserve coercivity of the scheme). # theta_bcs_r = { wp_boundary_indices["stamp"]: (100.0, 1500.0), wp_boundary_indices["surface"]: (100.0, 1550.0), wp_boundary_indices["right"]: (300.0, Expression("200*x[0] + 1600", degree=1)), wp_boundary_indices["lower"]: ( 300.0, Expression("-1200*x[1] + 1614", degree=1), ), } return ( mesh, subdomains, subdomain_materials, workpiece_index, wp_boundaries, W, u_bcs, p_bcs, Q, theta_bcs_d, theta_bcs_n, theta_bcs_r, )