def boundary(x, on_boundary): """ Test if x is on boundary. """ tol = 1e-14 return on_boundary and ((F.near(x[0], 0.0, tol)) or (F.near(x[0], length, tol)))
def boundary(x, on_boundary): ''' Test if x is on boundary. ''' tol = 1E-14 return on_boundary and ((F.near(x[0], 0., tol)) or (F.near(x[0], length, tol)))
def inside(self, x, on_boundary): tol = 1E-14 if on_boundary and not near(x[0], x_coupling, tol) or near( x[1], y_top, tol) or near(x[1], y_bottom, tol): return True else: return False
def is_near(self, pt): x, y = x if (fe.near(y, self.bottom) or fe.near(y, self.top)) \ and (x > self.left and x < self.right): return True else: return False
def inside(self, x, on_boundary): for d,eo in enumerate(self.evenodd): if ((self.dim <= 1 or on_boundary) and eo and (fe.near(x[d], self.xmin, self.tol) or fe.near(x[d], self.xmax, self.tol))): return(True) return(False)
def mesh_stats(mesh, tol=1e-7): """Find the dimensions and midpoints of a mesh. Required argument: mesh The mesh should be on an interval, square, or cube. Vertex points should be equally spaced in each dimension, and the spacing should be the same in each. Finally, there should be a vertex at the midpoint of the domain. meshstats returns a dict with keys xmin, xmax, xmid, dx. Each value is a single float number. Exceptions: mesh_stats raises a KSDGException if it detects that the conditions on the mesh are not met. """ dim = mesh.geometry().dim() comm = mesh.mpi_comm() if dim < 1 or dim > 3: raise KSDGException( "dimension of mesh = %d, must be 1, 2, or 3"%dim ) cs = gather_vertex_coords(mesh) stats = _cstats(cs, 0, tol=tol) for d in range(1, dim): dstats = _cstats(cs, d, tol=tol) if (not fe.near(stats['xmin'], dstats['xmin'], tol) or not fe.near(stats['xmax'], dstats['xmax'], tol) or not fe.near(stats['xmid'], dstats['xmid'], tol) or not fe.near(stats['dx'], dstats['dx'], tol)): raise KSDGException( "dimension %d spacing doesn't match dimension 0"%d ) return(stats)
def eval(self, value, pt): """ Set value[0] to self.current if x is on the active segment, or to 0 otherwise """ x, y = pt if (fe.near(y, bottom) or fe.near(y, top)) and x > left and x < right: value[0] = Im else: value[0] = 0
def eval(self, value, X): r = (np.pi * f0 * (self.t - 1./f0))**2 amp = (1. - 2.*r)*np.exp(-r) value[:] = 0 for i in range(np.shape(possou)[1]): xsou = possou[0, i] + pml ysou = possou[1, i] + pml if fn.near(X[0], xsou, self.tol) and fn.near(X[1], ysou, self.tol): value[:] = amp
def map(self, x, y): if fenics.near(x[0], 1) and fenics.near(x[1], 1): y[0] = x[0] - 1. y[1] = x[1] - 1. elif fenics.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): """ return True if on left or bottom boundary AND NOT on one of the two corners (0, 1) and (1, 0) """ zero_boundary = False one_boundary = False corner = True for ii in range(self.dim): zero_boundary = zero_boundary or near(x[ii], 0.) one_boundary = one_boundary or near(x[ii], 1.) corner = corner and (near(x[ii], 0.) or near(x[ii], 1.)) return bool(on_boundary and zero_boundary and not one_boundary)
def map(self, source, dest): """Identify the boundaries of the square.""" # Identify the point diagonally opposite to the origin to the origin if near(source[0], self.width) and near(source[1], self.height): dest[0] = 0.0 dest[1] = 0.0 # Identify the opposite edges elif near(source[0], self.width): dest[0] = 0.0 dest[1] = source[1] elif near(source[1], self.height): dest[0] = source[0] dest[1] = 0.0
def initial_mesh(self): self.initial_hot_wall_refinement_cycles = 8 mesh = self.coarse_mesh() for i in range(self.initial_hot_wall_refinement_cycles): cell_markers = fenics.MeshFunction("bool", mesh, mesh.topology().dim(), False) cell_markers.set_all(False) for cell in fenics.cells(mesh): found_left_boundary = False for vertex in fenics.vertices(cell): if fenics.near(vertex.x(0), 0.): found_left_boundary = True break if found_left_boundary: cell_markers[cell] = True break # There should only be one such point in 1D. mesh = fenics.refine(mesh, cell_markers) return mesh
def refine_near_left_boundary(mesh, cycles): """ Refine mesh near the left boundary. The usual approach of using SubDomain and EdgeFunction isn't appearing to work in 1D, so I'm going to just loop through the cells of the mesh and set markers manually. """ for i in range(cycles): cell_markers = fenics.CellFunction("bool", mesh) cell_markers.set_all(False) for cell in fenics.cells(mesh): found_left_boundary = False for vertex in fenics.vertices(cell): if fenics.near(vertex.x(0), 0.): found_left_boundary = True if found_left_boundary: cell_markers[cell] = True break # There should only be one such point. mesh = fenics.refine(mesh, cell_markers) return mesh
def make_ds(mesh): surface = AutoSubDomain(lambda x: "on_boundary" and near(x[0], 1)) boundaries = FacetFunction("size_t", mesh) boundaries.set_all(0) surface.mark(boundaries, 1) ds = Measure("ds", subdomain_data=boundaries) return ds
def refine_initial_mesh(self): """ Replace 2D refinement method with 3D method. Perhaps one could make an n-dimensional method. """ for i in range(self.initial_hot_wall_refinement_cycles): cell_markers = fenics.MeshFunction("bool", self.mesh, self.mesh.topology().dim(), False) for cell in fenics.cells(self.mesh): found_left_boundary = False for vertex in fenics.vertices(cell): if fenics.near(vertex.x(0), 0.): found_left_boundary = True break if found_left_boundary: cell_markers[cell] = True self.mesh = fenics.refine(self.mesh, cell_markers)
def refine_initial_mesh(self): """ Locally refine near the hot boundary """ for i in range(self.initial_hot_boundary_refinement_cycles): cell_markers = fenics.MeshFunction("bool", self.mesh, self.mesh.topology().dim(), False) cell_markers.set_all(False) for cell in fenics.cells(self.mesh): found_left_boundary = False for vertex in fenics.vertices(cell): if fenics.near(vertex.x(0), 0.): found_left_boundary = True break if found_left_boundary: cell_markers[cell] = True break # There should only be one such point in 1D. self.mesh = fenics.refine( self.mesh, cell_markers) # Does this break references?
def __init__(self): self.mesh = None self.vid = None # parameters self.water_in_flux = 0.1 self.boundary_fnc = lambda x: near(x[0], 1) and 0.3 < x[1] < 0.6
def map(self, pos_a, pos_b): """map pos_b onto pos_a""" if fe.near(pos_a[0], XMAX) and fe.near(pos_a[1], YMAX): pos_b[0] = pos_a[0] - (XMAX - XMIN) pos_b[1] = pos_a[1] - (YMAX - YMIN) pos_b[2] = pos_a[2] elif fe.near(pos_a[0], XMAX): pos_b[0] = pos_a[0] - (XMAX - XMIN) pos_b[1] = pos_a[1] pos_b[2] = pos_a[2] elif fe.near(pos_a[1], YMAX): pos_b[0] = pos_a[0] pos_b[1] = pos_a[1] - (YMAX - YMIN) pos_b[2] = pos_a[2] else: pos_b[0] = -1000 pos_b[1] = -1000 pos_b[2] = -1000
def map(self, pos_a, pos_b): """map pos_b onto pos_a""" if fe.near(pos_a[0], XMAX) and fe.near(pos_a[1], YMAX): pos_b[0] = pos_a[0] - (XMAX - XMIN) pos_b[1] = pos_a[1] - (YMAX - YMIN) pos_b[2] = pos_a[2] elif fe.near(pos_a[0], XMAX): pos_b[0] = pos_a[0] - (XMAX - XMIN) pos_b[1] = pos_a[1] pos_b[2] = pos_a[2] elif fe.near(pos_a[1], YMAX): pos_b[0] = pos_a[0] pos_b[1] = pos_a[1] - (YMAX - YMIN) pos_b[2] = pos_a[2] else: pos_b[0] = -1000 pos_b[1] = -1000 pos_b[2] = -1000
def map(self, source, dest): """Identifdest the boundaries of the cube.""" def vec_near(pt1, pt2): """Check if pt1 and pt2 are near each other numericalldest.""" return all([near(c1, c2) for (c1, c2) in zip(pt1, pt2)]) # pylint: disable=bad-whitespace corners = [(self.width, self.height, self.depth), (0.0, self.height, self.depth), (self.width, 0.0, self.depth), (self.width, self.height, 0.0), (0.0, 0.0, self.depth), (0.0, self.height, 0.0), (self.width, 0.0, 0.0)] # Identify all the other 7 corner points to the origin if any([vec_near(source, c) for c in corners]): dest[0] = 0.0 dest[1] = 0.0 dest[2] = 0.0 # Identify the 3 diagonally opposite edges to the coordinate axis elif near(source[0], self.width) and near(source[1], self.height): dest[0] = 0.0 dest[1] = 0.0 dest[2] = source[2] elif near(source[1], self.height) and near(source[2], self.depth): dest[0] = source[0] dest[1] = 0.0 dest[2] = 0.0 elif near(source[0], self.width) and near(source[2], self.depth): dest[0] = 0.0 dest[1] = source[1] dest[2] = 0.0 # Identify the opposite faces elif near(source[0], self.width): dest[0] = 0.0 dest[1] = source[1] dest[2] = source[2] elif near(source[1], self.height): dest[0] = source[0] dest[1] = 0.0 dest[2] = source[2] elif near(source[2], self.depth): dest[0] = source[0] dest[1] = source[1] dest[2] = 0.0
def inside(self, coor, on_boundary): """This defines the domain for the master nodes.""" # Master nodes are on the coordinate plane return ((near(coor[0], 0.0) or near(coor[1], 0.0) or near(coor[2], 0.0)) and (not (near(coor[0], self.width) or near(coor[1], self.height) or near(coor[2], self.depth))) and on_boundary)
def test_apply_boundary_conditions(): mesh = fenics.UnitIntervalMesh(10) V = fenics.FunctionSpace(mesh, 'P', 1) surface_markers = fenics.MeshFunction( "size_t", mesh, mesh.topology().dim()-1, 0) surface_markers.set_all(0) i = 0 for f in fenics.facets(mesh): i += 1 x0 = f.midpoint() surface_markers[f] = 0 if fenics.near(x0.x(), 0): surface_markers[f] = 1 if fenics.near(x0.x(), 1): surface_markers[f] = 2 boundary_conditions = [ { "surface": [1], "value": 0, "component": 0, "type": "dc" }, { "surface": [2], "value": 1, "type": "dc" } ] bcs, expressions = FESTIM.apply_boundary_conditions( boundary_conditions, V, surface_markers, 1, 300) assert len(bcs) == 2 assert len(expressions) == 2 u = fenics.Function(V) for bc in bcs: bc.apply(u.vector()) assert abs(u(0)-0) < 1e-15 assert abs(u(1)-1) < 1e-15
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( (fenics.near(x[0], 0) or fenics.near(x[1], 0)) and (not ((fenics.near(x[0], 0) and fenics.near(x[1], 1)) or (fenics.near(x[0], 1) and fenics.near(x[1], 0)))) and on_boundary)
def inside(self, pos, on_boundary): """ return True if on left (XMIN) or front (YMIN) boundary AND NOT on one of the two slave edges """ res = bool( (fe.near(pos[0], XMIN) or fe.near(pos[1], YMIN)) and not ( (fe.near(pos[0], XMAX) and fe.near(pos[1], YMIN)) or (fe.near(pos[0], XMIN) and fe.near(pos[1], YMAX)) ) and on_boundary) return res
def inside(self, pos, on_boundary): """ return True if on left (XMIN) or front (YMIN) boundary AND NOT on one of the two slave edges """ res = bool( (fe.near(pos[0], XMIN) or fe.near(pos[1], YMIN)) and not ((fe.near(pos[0], XMAX) and fe.near(pos[1], YMIN)) or (fe.near(pos[0], XMIN) and fe.near(pos[1], YMAX))) and on_boundary) return res
def eval(self, value, x): """ Set value[0] to 0 if x is on the box, or to CURRENT otherwise """ # for edge in (0, BOX_SIZE): # for coord in x: # if fe.near(coord, edge): # value[0] = 0 # return # rad_sq = (x[0] - 50)**2 + (x[1] - 10)**2 # print(x, rad_sq) # value[0] = CURRENT rad_sq = (x[0] - CYL_X)**2 + (x[1] - CYL_Y)**2 if fe.near(rad_sq, CYL_R**2): value[0] = CURRENT else: value[0] = 0
def inside(self, x, on_boundary): tol = 1E-14 if on_boundary and near(x[0], x_coupling, tol): return True else: return False
def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and fe.near(x[2], Dimensions[2]/2, tol)
def boundary_at_R(x, on_boundary): return on_boundary and near(x[0], 1, tol)
def boundary_B(x, on_boundary): return on_boundary and fen.near(x[1], -edge, tol)
def boundary_R(x, on_boundary): return on_boundary and fen.near(x[0], edge, tol)
def inside(self, x, on_boundary): tol = 1E-14 if on_boundary and near(x[1], y_bottom, tol): return True else: return False