def inside(self, x, on_boundary): if near(x[1], self.h1): x_top = between(x[0], [self.L1, self.L1 + self.b]) return on_boundary and x_top elif near(x[0], self.L1): y_left = between(x[1], [0., self.h1]) return on_boundary and y_left
def inside(self, x, on_bnd): return bool(on_bnd and (np.any([(df.near(a, 0) and not p) for a, p in zip(x, self.periodic)]) or # On non-periodic lower bound np.any([(df.near(a, b) and not p) for a, b, p in zip(x, self.Ld, self.periodic) ]))) # Or non-periodic upper bound
def checkPosition(self, x): return [ df.near(x[0], self.x0), df.near(x[1], self.y0), df.near(x[0], self.x1), df.near(x[1], self.y1) ]
def inside(self, x, on_bnd): return bool( on_bnd and any([ (df.near(a, 0) and p) for a, p in zip(x, self.periodic) ]) # On any periodic lower bound and not any([df.near(a, b) for a, b in zip(x, self.Ld)])) # But not any upper bound
def map(self, x, y): if near(x[0], self.xmax) and near(x[1], self.ymax): y[0] = x[0] - (self.xmax - self.xmin) y[1] = x[1] - (self.ymax - self.ymin) elif near(x[0], self.xmax): y[0] = x[0] - (self.xmax - self.xmin) y[1] = x[1] else: # near(x[1], 1) y[0] = x[0] y[1] = x[1] - (self.ymax - self.ymin)
def map(self, x, y): if df.near(x[0], self.Lx) and df.near(x[1], self.Ly): y[0] = x[0] - self.Lx y[1] = x[1] - self.Ly elif df.near(x[0], self.Lx): y[0] = x[0] - self.Lx y[1] = x[1] else: y[0] = x[0] y[1] = x[1] - self.Ly
def map(self, x, y): if df.near(x[0], 1) and df.near(x[1], 1): y[0] = x[0] - 1. y[1] = x[1] - 1. elif df.near(x[0], 1): y[0] = x[0] - 1. y[1] = x[1] else: # df.near(x[1], 1) y[0] = x[0] y[1] = x[1] - 1.
def map(self, x, y): if df.near(x[0], 1) and df.near(x[1], 1): y[0] = x[0] - 1. y[1] = x[1] - 1. elif df.near(x[0], 1): y[0] = x[0] - 1. y[1] = x[1] else: # near(x[1], 1) y[0] = x[0] y[1] = x[1] - 1.
def inside(self, x, on_boundary): y_top = near(x[1], self.h1) y_bot = near(x[1], -(self.h2 - self.h1)) y_clamp = y_top or y_bot x_right = near(x[0], self.L1 + self.L2) x_left = near(x[0], self.L1) y_left = x[1] < 0 + DOLFIN_EPS x_clamp = x_right or (x_left and y_left) return on_boundary and (y_clamp or x_clamp)
def getNode(self, point): x0 = point.x() y0 = point.y() z0 = point.z() coordinates = self.getCoordinates() for row in range(len(coordinates)): x = coordinates[row][0] y = coordinates[row][1] z = coordinates[row][2] if near(x, x0) and near(y, y0) and near(z, z0): return row
def map(self, x, y): xmin, xmax, ymin, ymax = self.xmin, self.xmax, self.ymin, self.ymax # If near top left corner if near(x[0], xmax) and near(x[1], ymax): y[0] = x[0] - (xmax - xmin) y[1] = x[1] - (ymax - ymin) elif near(x[0], xmax): y[0] = x[0] - (xmax - xmin) y[1] = x[1] else: y[0] = x[0] y[1] = x[1] - (ymax - ymin)
def inside(self, x, on_boundary): y_top = near(x[1], self.h + self.h) y_bot = near(x[1], -self.h) y_cond = y_top or y_bot x_right = near(x[0], self.L + self.L) x_left = near(x[0], self.L) and not between(x[1], [0., self.h]) x_cond = x_right or x_left cond = y_cond or x_cond return on_boundary and cond
def map(self, x, y): y[0] = x[0] - 1.0 y[1] = x[1] - 1.0 if df.near(x[0], 1) and x[1] < 1.0: y[1] = x[1] if df.near(x[1], 1) and x[0] < 1.0: y[0] = x[0] y[2] = x[2] print x, y
def map(self, x, y): y[0] = x[0] - self.width y[1] = x[1] - self.height if self.dim == 3: y[2] = x[2] if df.near(x[0], self.xmax) and x[1] < self.ymax: y[1] = x[1] if df.near(x[1], self.ymax) and x[0] < self.xmax: y[0] = x[0]
def getNodesAlongAxis(self, axis, axis0=0.0): nodes = [] coordinates = self.getCoordinates() for j, row in enumerate(coordinates): appendRow = True for i, coord in enumerate(row): if i != axis and near(coord, axis0): appendRow = appendRow and True elif i != axis and not near(coord, axis0): appendRow = appendRow and False if appendRow: nodes.append(j) return nodes
def map(self, x, y): if df.near(x[0], self.Lx / 2.) and df.near(x[1], self.Ly / 2.): y[0] = x[0] - self.Lx y[1] = x[1] - self.Ly y[2] = x[2] elif df.near(x[0], self.Lx / 2.): y[0] = x[0] - self.Lx y[1] = x[1] y[2] = x[2] else: # near(x[1], Ly/2.): y[0] = x[0] y[1] = x[1] - self.Ly y[2] = x[2]
def meshxml(name): # reads mesh from .xml file, cf. Notes # IN: str of name of the .xml file (do that in serial): mesh = dolfin.Mesh(name + '.xml') mesh.init() hdf = dolfin.HDF5File(mesh.mpi_comm(), name + "_hdf.h5", "w") hdf.write(mesh, "/mesh") xdmf = dolfin.XDMFFile(mesh.mpi_comm(), name + "_xdmf.xdmf") xdmf.write(mesh) xdmf.close() domains = mesh.domains() if os.path.isfile(name + "_physical_region.xml"): domains.init(mesh.topology().dim() - 1) if os.path.isfile(name + "_facet_region.xml"): boundary = (dolfin.MeshFunction("size_t", mesh, name + "_facet_region.xml"), { 'inner': 1, 'outer': 2 }) #mesh.init() hdf.write(boundary[0], "/boundary") ds = dolfin.Measure("ds", subdomain_data=boundary[0]) else: boundary = (dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0), {}) width = mesh.coordinates()[:, 0].max() height = mesh.coordinates()[:, 1].max() for f in dolfin.facets(mesh): if dolfin.near(f.midpoint()[1], 0.): boundary[0][f] = 1 # bottom boundary[1]['bottom'] = 1 elif dolfin.near(f.midpoint()[1], height): boundary[0][f] = 2 # top boundary[1]['top'] = 2 elif dolfin.near(f.midpoint()[0], 0.): boundary[0][f] = 3 # left boundary[1]['left'] = 3 elif dolfin.near(f.midpoint()[0], width): boundary[0][f] = 4 # right boundary[1]['right'] = 4 ds = dolfin.Measure("ds", subdomain_data=boundary[0]) # mesh = Mesh() # hdf.read(mesh,"/mesh", False) hdf.close() # Definition of measures and normal vector: n = dolfin.FacetNormal(mesh) dx = dolfin.Measure("dx", mesh) return (mesh, boundary, n, dx, ds)
def mesh2d(inner, outer, *meshres, stefan=True): origin = dolfin.Point(0., 0.) if stefan: geometry = mshr.Circle(origin, outer, 2 * meshres[0]) - mshr.Circle( origin, inner, int(0.5 * meshres[0])) mesh = mshr.generate_mesh(geometry, meshres[0]) mesh.init() # Construct of the facet markers: boundary = (dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0), {}) for f in dolfin.facets(mesh): if f.midpoint().distance(origin) <= inner and f.exterior(): boundary[0][f] = 1 # inner radius boundary[1]['inner'] = 1 elif f.midpoint().distance(origin) >= (inner + outer) / 2 and f.exterior(): boundary[0][f] = 2 # outer radius boundary[1]['outer'] = 2 # Definition of measures and normal vector: n = dolfin.FacetNormal(mesh) dx = dolfin.Measure("dx", mesh) ds = dolfin.Measure("ds", domain=mesh, subdomain_data=boundary[0]) else: width = inner height = outer mesh = dolfin.RectangleMesh(origin, Point(width, height), meshres[0], meshres[1]) mesh.init() boundary = (dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0), {}) for f in dolfin.facets(mesh): if dolfin.near(f.midpoint()[1], 0.): boundary[0][f] = 1 # bottom boundary[1]['bottom'] = 1 elif dolfin.near(f.midpoint()[1], height): boundary[0][f] = 2 # top boundary[1]['top'] = 2 elif dolfin.near(f.midpoint()[0], 0.): boundary[0][f] = 3 # left boundary[1]['left'] = 3 elif dolfin.near(f.midpoint()[0], width): boundary[0][f] = 4 # right boundary[1]['right'] = 4 # Definition of measures and normal vector: n = dolfin.FacetNormal(mesh) dx = dolfin.Measure("dx", mesh) ds = dolfin.Measure("ds", subdomain_data=boundary[0]) return (mesh, boundary, n, dx, ds)
def test_pointsource_matrix_second_constructor(mesh, point): """Tests point source when given different constructor PointSource(V1, V2, point, mag) with a matrix and when placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. Currently only implemented if V1=V2. """ V1 = FunctionSpace(mesh, "CG", 1) V2 = FunctionSpace(mesh, "CG", 1) rank = MPI.rank(mesh.mpi_comm()) u, v = TrialFunction(V1), TestFunction(V2) w = Function(V1) A = assemble(Constant(0.0) * u * v * dx) if rank == 0: ps = PointSource(V1, V2, point, 10.0) else: ps = PointSource(V1, V2, []) ps.apply(A) # Checks array sums to correct value a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array())) assert round(a_sum - 10.0) == 0 # Checks point source is added to correct part of the array A.get_diagonal(w.vector()) v2d = vertex_to_dof_map(V1) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): ind = v2d[v.index()] if ind < len(A.array()): assert np.round(w.vector()[ind] - 10.0) == 0
def test_pointsource_vector_fs(mesh, point): """Tests point source when given constructor PointSource(V, point, mag) with a vector for a vector function space that isn't placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ rank = MPI.rank(mesh.mpi_comm()) V = VectorFunctionSpace(mesh, "CG", 1) v = TestFunction(V) b = assemble(dot(Constant([0.0] * mesh.geometry().dim()), v) * dx) if rank == 0: ps = PointSource(V, point, 10.0) else: ps = PointSource(V, []) ps.apply(b) # Checks array sums to correct value b_sum = b.sum() assert round(b_sum - 10.0 * V.num_sub_spaces()) == 0 # Checks point source is added to correct part of the array v2d = vertex_to_dof_map(V) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): for spc_idx in range(V.num_sub_spaces()): ind = v2d[v.index() * V.num_sub_spaces() + spc_idx] if ind < len(b.get_local()): assert np.round(b.get_local()[ind] - 10.0) == 0
def map(self, x, y): if df.near(x[0], self.Lx): y[0] = x[0] - self.Lx y[1] = x[1] else: # near(x[2], Lz/2.): y[0] = x[0] y[1] = x[1]
def test_pointsource_vector_fs(mesh, point): """Tests point source when given constructor PointSource(V, point, mag) with a vector for a vector function space that isn't placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ rank = MPI.rank(mesh.mpi_comm()) V = VectorFunctionSpace(mesh, "CG", 1) v = TestFunction(V) b = assemble(dot(Constant([0.0]*mesh.geometry().dim()), v)*dx) if rank == 0: ps = PointSource(V, point, 10.0) else: ps = PointSource(V, []) ps.apply(b) # Checks array sums to correct value b_sum = b.sum() assert round(b_sum - 10.0*V.num_sub_spaces()) == 0 # Checks point source is added to correct part of the array v2d = vertex_to_dof_map(V) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): for spc_idx in range(V.num_sub_spaces()): ind = v2d[v.index()*V.num_sub_spaces() + spc_idx] if ind < len(b.get_local()): assert np.round(b.get_local()[ind] - 10.0) == 0
def test_pointsource_matrix_second_constructor(mesh, point): """Tests point source when given different constructor PointSource(V1, V2, point, mag) with a matrix and when placed at a node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. Currently only implemented if V1=V2. """ V1 = FunctionSpace(mesh, "CG", 1) V2 = FunctionSpace(mesh, "CG", 1) rank = MPI.rank(mesh.mpi_comm()) u, v = TrialFunction(V1), TestFunction(V2) w = Function(V1) A = assemble(Constant(0.0)*u*v*dx) if rank == 0: ps = PointSource(V1, V2, point, 10.0) else: ps = PointSource(V1, V2, []) ps.apply(A) # Checks array sums to correct value a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array())) assert round(a_sum - 10.0) == 0 # Checks point source is added to correct part of the array A.get_diagonal(w.vector()) v2d = vertex_to_dof_map(V1) for v in vertices(mesh): if near(v.midpoint().distance(point), 0.0): ind = v2d[v.index()] if ind < len(A.array()): assert np.round(w.vector()[ind] - 10.0) == 0
def test_cell_midpoints(D): from ocellaris.solver_parts.slope_limiter.limiter_cpp_utils import SlopeLimiterInput if D == 2: mesh = dolfin.UnitSquareMesh(4, 4) else: mesh = dolfin.UnitCubeMesh(2, 2, 2) Vx = dolfin.FunctionSpace(mesh, 'DG', 2) V0 = dolfin.FunctionSpace(mesh, 'DG', 0) py_inp = SlopeLimiterInput(mesh, Vx, V0) cpp_inp = py_inp.cpp_obj all_ok = True for cell in dolfin.cells(mesh): cid = cell.index() mp = cell.midpoint() cpp_mp = cpp_inp.cell_midpoints[cid] for d in range(D): ok = dolfin.near(mp[d], cpp_mp[d]) if not ok: print( '%3d %d - %10.3e %10.3e' % (cid, d, mp[d], cpp_mp[d]), '<--- ERROR' if not ok else '', ) all_ok = False assert all_ok
def map(self, x, y): SlaveT = fe.near(x[1], L_y / 2.0, self.tol) if SlaveT: for i in range(len(x[:])): y[i] = (x[i] - L_y) if i == 1 else x[i] else: for i in range(len(x[:])): y[i] = 1000.0 * (L_x + L_y)
def map(self, x, y): if dolfin.near(x[0], self.x_max) and dolfin.near(x[1], self.y_max): y[0] = x[0] - self.x_max + self.x_min y[1] = x[1] - self.y_max + self.y_min y[2] = x[2] elif dolfin.near(x[0], self.x_max): y[0] = x[0] - self.x_max + self.x_min y[1] = x[1] y[2] = x[2] elif dolfin.near(x[1], self.y_max): y[0] = x[0] y[1] = x[1] - self.y_max + self.y_min y[2] = x[2] else: y[0] = (self.x_max + self.x_min) / 2 y[1] = (self.y_max + self.y_min) / 2 y[2] = x[2]
def __init__(self, mesh, Vh_STATE, x0): """ Constructor. INPUTS: - mesh: the mesh - Vh_STATE: the finite element space for the state variable - x0: location at which we want to compute the jet-thickness """ Vh_help = dl.FunctionSpace(mesh, "CG", 1) xfun = dl.interpolate(dl.Expression("x[0]", degree=1), Vh_help) x_coord = xfun.vector().gather_on_zero() mpi_comm = mesh.mpi_comm() rank = dl.MPI.rank(mpi_comm) nproc = dl.MPI.size(mpi_comm) # round x0 so that it is aligned with the mesh if nproc > 1: from mpi4py import MPI comm = MPI.COMM_WORLD if rank == 0: idx = (np.abs(x_coord - x0)).argmin() self.x0 = x_coord[idx] else: self.x0 = None self.x0 = comm.bcast(self.x0, root=0) else: idx = (np.abs(x_coord - x0)).argmin() self.x0 = x_coord[idx] line_segment = dl.AutoSubDomain(lambda x: dl.near(x[0], self.x0)) markers_f = dl.FacetFunction("size_t", mesh) markers_f.set_all(0) line_segment.mark(markers_f, 1) dS = dl.dS[markers_f] x_test = dl.TestFunctions(Vh_STATE) u_test = x_test[0] e1 = dl.Constant(("1.", "0.")) self.int_u = dl.assemble(dl.avg(dl.dot(u_test, e1)) * dS(1)) #self.u_cl = dl.assemble( dl.dot(u_test,e1)*dP(1) ) self.u_cl = dl.Function(Vh_STATE).vector() ps = dl.PointSource(Vh_STATE.sub(0).sub(0), dl.Point(self.x0, 0.), 1.) ps.apply(self.u_cl) scaling = self.u_cl.sum() if np.abs(scaling - 1.) > 1e-6: print scaling raise ValueError() self.state = dl.Function(Vh_STATE).vector() self.help = dl.Function(Vh_STATE).vector()
def mesh1d(left, right, meshres): mesh = dolfin.IntervalMesh(meshres, left, right) # Construct of the facet markers: boundary = (dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0), {}) #boundary[0].set_all(0) for f in dolfin.facets(mesh): if dolfin.near(f.midpoint()[0], left): boundary[0][f] = 1 # left boundary[1]['inner'] = 1 elif dolfin.near(f.midpoint()[0], right): boundary[0][f] = 2 # right boundary[1]['outer'] = 2 # Definition of measures and normal vector: n = dolfin.FacetNormal(mesh) dx = dolfin.Measure("dx", mesh) ds = dolfin.Measure("ds", subdomain_data=boundary[0]) return (mesh, boundary, n, dx, ds)
def map(self, x, y): for j in range(self.ndim): if dl.near(x[j], 1): y[j] = x[j] - 1 else: y[j] = x[j] #######################################################################################################
def get_voronoi_points(V, Ld, periodic, tol=1e-13): """ Returns the center points (in 3D) of the Voronoi diagram being the dual of the mesh of function space V. It also returns the corresponding FEniCS DOF index of each point: points, indices = get_voronoi_points(V, Ld, periodic) Ld is the size of the mesh and periodic is a list of three bools signifying whether each dimension is periodic or not. Points within tol of the boundary are shifted an amount tol inwards. """ # All center points are vertices in the Delaunay mesh. Let them be 3D. mesh = V.mesh() N = mesh.num_vertices() dim = mesh.geometry().dim() points = np.zeros((N, 3)) points[:, :dim] = mesh.coordinates() # replace with df.vertices(mesh)? dof_indices = df.vertex_to_dof_map(V) # Remove vertices on upper periodic boundaries i = 0 while i < len(points): if any([ df.near(a, b, tol) and p for a, b, p in zip(points[i], list(Ld), periodic) ]): points = np.delete(points, [i], axis=0) dof_indices = np.delete(dof_indices, [i], axis=0) else: i = i + 1 # Shift points on boundary inwards for d in range(3): points[:, d] = [ x + tol if df.near(x, 0, tol) else x for x in points[:, d] ] points[:, d] = [ x - tol if df.near(x, Ld[d], tol) else x for x in points[:, d] ] return points, dof_indices
def fill_coordinates_ec(i, e_c_x, e_c_y, e_c_z, coord, foci): norm = dolfin.sqrt(coord[1]**2 + coord[2]**2) if not dolfin.near(norm, 0): e_c_y.vector()[i] = -coord[2] / norm e_c_z.vector()[i] = coord[1] / norm else: # We are at the apex where crl system doesn't make sense # So just pick something. e_c_y.vector()[i] = 1 e_c_z.vector()[i] = 0
def inside(self, x, on_boundary): # # Define relevant points xb1 = (L_wall - L_sleeve - t_sleeve - t_gap) xb2 = (L_wall - L_sleeve) yb1 = t_wall yb2 = (t_wall + t_sleeve + t_gap) # # Define params for assessing if on a line between points dx_line = xb2 - xb1 dy_line = yb2 - yb1 dx = x[0] - xb1 dy = x[1] - yb1 zero = dx * dy_line - dx_line * dy # is_upper_region_one = x[0] <= xb1 and near(x[1], yb1) is_upper_region_two = x[0] >= xb1 and x[0] <= xb2 and near(zero, 0) is_upper_region_three = x[0] >= xb2 and near(x[1], yb2) # return is_upper_region_one or is_upper_region_two or is_upper_region_three
def inside(self, x, on_boundary): # return True if on left or bottom boundary AND NOT on one of the two corners (0, 1) and (1, 0) return bool( (df.near(x[0], 0) or df.near(x[1], 0)) and (not ((df.near(x[0], 0) and df.near(x[1], 1)) or (df.near(x[0], 1) and df.near(x[1], 0)))) and on_boundary)
def bzo_boundary(r_vec, on_boundary): # NB: input r_vec is a position vector r,theta,z = cart_to_cyl(x) # NB: check the function cart_to_cyl can take non-tuple collecs. return d.near(r,bzo_radius)
def inside(self, x, on_boundary): return on_boundary and dolfin.near(x[0], 0.0)
def inside(self, x, on_boundary): return not bool((dolfin.near(x[0], self.b)) and on_boundary)
def map(self, x, y): if dolfin.near(x[0], self.b): y[0] = self.a + (x[0] - self.b)
def inside(self, x, on_boundary): return on_boundary and (dolfin.near(x[1], y0) or dolfin.near(x[1], y1))
n0, dt0 = n, dt # Check creation mesh = df.UnitCubeMesh(10, 10, 10) f = df.MeshFunction('size_t', mesh, mesh.topology().dim()-1, 0) chi = df.CompiledSubDomain('near(x[i], 0.5)', i=0) for i in range(3): chi.i=i chi.mark(f, i+1) mesh = EmbeddedMesh(f, [1, 2, 3]) volume = lambda c: df.Cell(mesh, c.index()).volume() assert df.near(sum(volume(c) for c in df.SubsetIterator(mesh.marking_function, 1)), 1, 1E-10) assert df.near(sum(volume(c) for c in df.SubsetIterator(mesh.marking_function, 2)), 1, 1E-10) assert df.near(sum(volume(c) for c in df.SubsetIterator(mesh.marking_function, 3)), 1, 1E-10) # Check normla computation mesh = df.UnitCubeMesh(10, 10, 10) bmesh = df.BoundaryMesh(mesh, 'exterior') n = OuterNormal(bmesh, [0.5, 0.5, 0.5]) for cell in df.cells(bmesh): x = cell.midpoint().array() if df.near(x[0], 0): assert np.linalg.norm(n(x) - np.array([-1, 0, 0])) < 1E-10 elif df.near(x[0], 1.): assert np.linalg.norm(n(x) - np.array([1, 0, 0])) < 1E-10
def bottom(x, on_boundary): return on_boundary and near(x[2], 0.0)
def right(x, on_boundary): return on_boundary and near(x[0], mesh_width)
def bottom(x, on_boundary): return on_boundary and near(x[1], 0.0) def left(x, on_boundary): return on_boundary and x[1] < LAB(x) and near(x[0], 0.0)
def left(x, on_boundary): return on_boundary and x[1] < LAB(x) and near(x[0], 0.0) def right(x, on_boundary): return on_boundary and x[1] < LAB(x) and near(x[0], MeshWidth)
def inside(s, x, on_boundary): return on_boundary and d.near(x[0], self.L)
def inside(self, x, on_boundary): return dolfin.near(x[0], 1.0)
def top(x, on_boundary): return on_boundary and near(x[2], mesh_height)
def back(x, on_boundary): return on_boundary and near(x[1], mesh_width)
def right(x, on_boundary): return on_boundary and x[1] < LAB(x) and near(x[0], MeshWidth) def RunJob(Tb, mu_value, path):
def left(x, on_boundary): return on_boundary and near(x[0], 0.0)
def inside(self, x, on_boundary): # return True if on left or bottom boundary AND NOT on one of the two corners (0, 1) and (1, 0) return bool((df.near(x[0], 0) or df.near(x[1], 0)) and (not ((df.near(x[0], 0) and df.near(x[1], 1)) or (df.near(x[0], 1) and df.near(x[1], 0)))) and on_boundary)
return emesh # ------------------------------------------------------------------- if __name__ == '__main__': mesh = df.UnitSquareMesh(4, 4) subdomains = df.MeshFunction('size_t', mesh, mesh.topology().dim(), 3) df.CompiledSubDomain('x[0] < 0.25+DOLFIN_EPS').mark(subdomains, 1) df.CompiledSubDomain('x[0] > 0.75-DOLFIN_EPS').mark(subdomains, 2) mesh1 = SubDomainMesh(subdomains, (1, 3)) mesh2 = SubDomainMesh(subdomains, (2, 3)) mesh12 = OverlapMesh(mesh1, mesh2) # FIXME: split the file! map1 = mesh12.parent_entity_map[mesh1.id()][2] map2 = mesh12.parent_entity_map[mesh2.id()][2] # Cell check out for c, c1, c2 in zip(df.cells(mesh12), map1, map2): assert df.near(c.midpoint().distance(df.Cell(mesh1, c1).midpoint()), 0, 1E-14) assert df.near(c.midpoint().distance(df.Cell(mesh2, c2).midpoint()), 0, 1E-14) # Vertices are not that important but anyways x1 = mesh1.coordinates(); map1 = mesh12.parent_entity_map[mesh1.id()][0] x2 = mesh2.coordinates(); map2 = mesh12.parent_entity_map[mesh2.id()][0] for x, i1, i2 in zip(mesh12.coordinates(), map1, map2): assert np.linalg.norm(x - x1[i1]) < 1E-13 assert np.linalg.norm(x - x2[i2]) < 1E-13
def top(x, on_boundary): return on_boundary and near(x[1], MeshHeight) def bottom(x, on_boundary): return on_boundary and near(x[1], 0.0)
def mortar_meshes(subdomains, markers, ifacet_iter=None, strict=True, tol=1E-14): ''' Let subdomains a cell function. We assume that domains (cells) marked with the given markers are adjecent and an interface can be defined between these domains which is a continuous curve. Then for each domain we create a (sub)mesh and a single interface mesh which holds a connectivity map of its cells to facets of the submeshes. The submeshes are returned as a list. The connectivity map is of the form submesh.id -> facets. The marking function f of the EmbeddedMesh that is the interface is colored such that f[color] is the interface of meshes (submeshes[m] for m color_map[color]). ''' assert len(markers) > 1 # Need a cell function mesh = subdomains.mesh() tdim = mesh.topology().dim() assert subdomains.dim() == tdim markers = list(markers) # For each facet we want to know which 2 cells share it tagged_iface = defaultdict(dict) if ifacet_iter is None: mesh.init(tdim-1) ifacet_iter = df.facets(mesh) mesh.init(tdim-1, tdim) for facet in ifacet_iter: cells = map(int, facet.entities(tdim)) if len(cells) > 1: c0, c1 = cells tag0, tag1 = subdomains[c0], subdomains[c1] if tag0 != tag1 and tag0 in markers and tag1 in markers: # A key of sorted tags if tag0 < tag1: key = (tag0, tag1) # The cells connected to facet order to match to tags value = (c0, c1) else: key = (tag1, tag0) value = (c1, c0) # A facet to 2 cells map for the facets of tagged pair tagged_iface[key][facet.index()] = value # order -> tagged keys color_to_tag_map = tagged_iface.keys() # Set to color which won't be encounred interface = df.MeshFunction('size_t', mesh, tdim-1, len(color_to_tag_map)) values = interface.array() # Mark facets corresponding to tagged pair by a color for color, tags in enumerate(color_to_tag_map): values[tagged_iface[tags].keys()] = color # Finally create an interface mesh for all the colors interface_mesh = EmbeddedMesh(interface, range(len(color_to_tag_map))) # Try to recogninze the meshes which violates assumptions by counting assert not strict or is_continuous(interface_mesh) # And subdomain mesh for each marker subdomain_meshes = {tag: EmbeddedMesh(subdomains, tag) for tag in markers} # Alloc the entity maps for the embedded mesh interface_map = {subdomain_meshes[tag].id(): [None]*interface_mesh.num_cells() for tag in markers} # THe maps are filled by the following idea. Using marking function # of interface mesh one cat get cells of that color and useing entity # map for (original) mesh map the cells to mesh facet. A color also # corresponds to a pair of tags which identifies the two meshes which # share the facet - facet connected to 2 cells one for each mesh. The # final step is to lean to map submesh cells to mesh cells # local submesh <- global of parent mesh sub_mesh_map = lambda tag: dict( (mesh_c, submesh_c) for submesh_c, mesh_c in enumerate(subdomain_meshes[tag].parent_entity_map[mesh.id()][tdim]) ) # Thec cell-cell connectivity of each submesh c2c = {tag: sub_mesh_map(tag) for tag in markers} # A connectivity of interface mesh cells to facets of global mesh c2f = interface_mesh.parent_entity_map[mesh.id()][tdim-1] for color, tags in enumerate(color_to_tag_map): # Precompute for the 2 tags submeshes = [subdomain_meshes[tag] for tag in tags] for cell in df.SubsetIterator(interface_mesh.marking_function, color): cell_index = cell.index() # The corresponding global cell facet facet = c2f[cell_index] # The two cells in global mesh numbering global_cells = tagged_iface[tags][facet] # Let's find the facet in submesh for tag, gc, submesh in zip(tags, global_cells, submeshes): # The map uses local cell local_cell = c2c[tag][gc] mesh_id = submesh.id() found = False for submesh_facet in df.facets(df.Cell(submesh, local_cell)): found = df.near(cell.midpoint().distance(submesh_facet.midpoint()), 0, tol) if found: interface_map[mesh_id][cell_index] = submesh_facet.index() break # Collapse to list; I want list indexing subdomain_meshes = np.array([subdomain_meshes[m] for m in markers]) color_map = [map(markers.index, tags) for tags in color_to_tag_map] # Parent in the sense that the colored piece of interface # could have been created from mesh interface_mesh.parent_entity_map.update( dict((k, {tdim-1: v}) for k, v in interface_map.items()) ) return subdomain_meshes, interface_mesh, color_map
def front(x, on_boundary): return on_boundary and near(x[1], 0.0)
def inside(self, x, on_boundary): return on_boundary and dolfin.near(x[0], MIN_X_DIM)
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) # Overload post_import_problem to choose between the two cases def post_import_problem(NS_parameters, commandline_kwargs, **NS_namespace): """ Choose case - case could be defined through command line.""" NS_parameters.update(commandline_kwargs) case = NS_parameters['case'] if 'case' in NS_parameters else 1 Um = cases[case]["Um"] Re = cases[case]["Re"] Umean = 2./3.* Um nu = Umean*D/Re NS_parameters.update(nu=nu, Re=Re, Um=Um, Umean=Umean) return NS_parameters
def inside(self, x, on_boundary): return near(x[1], 1.0)
def inside(self, x, on_boundary): return on_boundary and near(x[0], x_min)
# If we want a scalar function with twice # the values of f1 (THIS WORKS) vec = df.assemble(df.dot(2 * f1, df.TestFunction(space_S1)) * df.dP) f2.vector().axpy(1, vec) # Now we want to modify the vector function space # to get the vector (2, 1, 1) in every vertex vec = df.assemble(df.dot(df.as_vector((2 * f1, f1, f1)), df.TestFunction(space_S3)) * df.dP) f3.vector().axpy(1, vec) # Scalar space assign g2 = df.Function(space_S1) g2.assign(df.FunctionAXPY(f1, 2.)) g2.vector().axpy(-1, f2.vector()) assert df.near(g2.vector().norm('l2'), 0) # Assigner for components of the vector space S3_assigners = [df.FunctionAssigner(space_S3.sub(i), space_S1) for i in range(space_S3.num_sub_spaces())] g3 = df.Function(space_S3) # Assign to components comps = [f2, f1, f1] [S3_assigners[i].assign(g3.sub(i), comp) for i, comp in enumerate(comps)] g3.vector().axpy(-1, f3.vector()) assert df.near(g3.vector().norm('l2'), 0) df.plot(f2) df.plot(f3)
def inside(self, x, on_boundary): dx = x[0] - c_x dy = x[1] - c_y dr = sqrt(dx**2 + dy**2) return on_boundary and (near(x[1]*(y_max - x[1]), 0) or dr < r + 1E-3)