def load(self): # Convert mesh from MSH to Dolfin-XML shutil.copyfile("input/%s.msh" % input_mesh, "%s.msh" % input_mesh) destination_xml = "%s.xml" % input_mesh subprocess.call( ["dolfin-convert", "%s.msh" % input_mesh, destination_xml]) # Load mesh and boundaries mesh = d.Mesh(destination_xml) self.patches = d.MeshFunction("size_t", mesh, "%s_facet_region.xml" % input_mesh) self.subdomains = d.MeshFunction("size_t", mesh, "%s_physical_region.xml" % input_mesh) # Define differential over subdomains self.dxs = d.dx[self.subdomains] # Turn subdomains into a Numpy array self.subdomains_array = N.asarray(self.subdomains.array(), dtype=N.int32) # Create a map from subdomain indices to tissues self.tissues_by_subdomain = {} for i, t in v.tissues.items(): print(i, t) for j in t["indices"]: self.tissues_by_subdomain[j] = t self.mesh = mesh self.setup_fe() self.prepare_increase_conductivity()
def SetupUnitMeshHelper(mesh, V=None, Vc=None): if V is None: V = df.FunctionSpace(mesh, 'CG', 1) if Vc is None: Vc = df.FunctionSpace(mesh, 'DG', 0) boundaries = dict() boundaries['left'] = df.CompiledSubDomain("near(x[0], 0.0) && on_boundary") boundaries['bottom'] = df.CompiledSubDomain( "near(x[1], 0.0) && on_boundary") boundaries['top'] = df.CompiledSubDomain("near(x[1], 1.0) && on_boundary") boundaries['right'] = df.CompiledSubDomain( "near(x[0], 1.0) && on_boundary") boundarymarkers = df.MeshFunction('size_t', mesh, mesh.topology().dim() - 1, 0) boundarymarkers.set_all(0) domainmarkers = df.MeshFunction('size_t', mesh, mesh.topology().dim(), 0) boundaries['left'].mark(boundarymarkers, 1) boundaries['bottom'].mark(boundarymarkers, 2) boundaries['right'].mark(boundarymarkers, 3) boundaries['top'].mark(boundarymarkers, 4) ds = df.Measure('ds', domain=mesh, subdomain_data=boundarymarkers) dx = df.Measure('dx', domain=mesh, subdomain_data=domainmarkers) return boundaries, boundarymarkers, domainmarkers, dx, ds, V, Vc
def meshReader(dictMesh): ''' converts json mesh to fenics mesh and apply the boundary conditions. dict:: dictMesh, the mesh from database in the form of a python dictionary output: dolfin.ccp.mesh:: feMesh, mesh defined in fenics object ''' # conver dict to object mesh = namedtuple("mesh", dictMesh.keys())(*dictMesh.values()) nodes = np.array(mesh.nodes) cells = np.array(mesh.connectivity, dtype=np.uintp) feMesh = fn.Mesh() editor = fn.MeshEditor() # cell type, topological, and geometrical dimensions. i.e. 2, 3 for 3d surface mesh editor.open(feMesh, "triangle", 2, 3) # cell types available: point, interval, triangle, quadrilateral, tetrahedron, hexahedron editor.init_vertices(len(mesh.nodes)) editor.init_cells(len(mesh.connectivity)) [editor.add_vertex(i, n) for i, n in enumerate(nodes)] [editor.add_cell(i, n - 1) for i, n in enumerate(cells)] editor.close() # construct faces faceSets = fn.MeshFunction('size_t', feMesh, 2) for face, faceCells in mesh.faces.items(): for index in faceCells: faceSets.set_value(index, int(face), feMesh) # construct edges edgeSets = fn.MeshFunction('size_t', feMesh, 1) meshEdges = {} for edge in fn.edges(feMesh): meshEdges[edge.index()] = [] for vert in fn.vertices(edge): meshEdges[edge.index()].append(vert.index()) for edge, nodes in meshEdges.items(): for edgeName, edgeList in mesh.edges.items(): if nodes in edgeList: edgeSets.set_value(edge, int(edgeName), feMesh) # construct points pointSets = fn.MeshFunction('size_t', feMesh, 0) for pointName, point in mesh.points.items(): pointSets.set_value(point, int(pointName), feMesh) return dict(feMesh=feMesh, faceSets=faceSets, edgeSets=edgeSets, pointSets=pointSets)
def calTrueSol(para): nx, ny = para['mesh_N'][0], para['mesh_N'][1] mesh = fe.UnitSquareMesh(nx, ny) Vu = fe.FunctionSpace(mesh, 'P', para['P']) Vc = fe.FunctionSpace(mesh, 'P', para['P']) al = fe.Constant(para['alpha']) f = fe.Expression(para['f'], degree=5) q1 = fe.interpolate(fe.Expression(para['q1'], degree=5), Vc) q2 = fe.interpolate(fe.Expression(para['q2'], degree=5), Vc) q3 = fe.interpolate(fe.Expression(para['q3'], degree=5), Vc) theta = fe.interpolate(fe.Expression(para['q4'], degree=5), Vc) class BoundaryX0(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[0], 0.0) class BoundaryX1(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[0], 1.0) class BoundaryY0(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[1], 0.0) class BoundaryY1(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[1], 1.0) boundaries = fe.MeshFunction('size_t', mesh, mesh.topology().dim() - 1) boundaries.set_all(0) bc0, bc1, bc2, bc3 = BoundaryX0(), BoundaryX1(), BoundaryY0(), BoundaryY1() bc0.mark(boundaries, 1) bc1.mark(boundaries, 2) bc2.mark(boundaries, 3) bc3.mark(boundaries, 4) domains = fe.MeshFunction("size_t", mesh, mesh.topology().dim()) domains.set_all(0) bcD = fe.DirichletBC(Vu, theta, boundaries, 4) dx = fe.Measure('dx', domain=mesh, subdomain_data=domains) ds = fe.Measure('ds', domain=mesh, subdomain_data=boundaries) u_trial, u_test = fe.TrialFunction(Vu), fe.TestFunction(Vu) u = fe.Function(Vu) left = fe.inner(al * fe.nabla_grad(u_trial), fe.nabla_grad(u_test)) * dx right = f * u_test * dx + (q1 * u_test * ds(1) + q2 * u_test * ds(2) + q3 * u_test * ds(3)) left_m, right_m = fe.assemble_system(left, right, bcD) fe.solve(left_m, u.vector(), right_m) return u
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 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 readCellExpression(self, group_value_dict, value_type="scalar", overlap=lambda x: x[0], *args, **kwargs): """ Reads cell expression and returns it. """ value_type_dictionary = { "scalar": ScalarCellExpressionFromXDMF, "vector2d": Vector2DCellExpressionFromXDMF, "vector3d": Vector3DCellExpressionFromXDMF } self.readMesh() xdmffile = fenics.XDMFFile(self.xdmffilename) cf = value_type_dictionary[value_type.lower()](group_value_dict, overlap=overlap, *args, **kwargs) cf.init() for (key, value) in cf.group_value_dict.items(): cf.markers[key] = fenics.MeshFunction("size_t", self.mesh, self.mesh.topology().dim()) xdmffile.read(cf.markers[key], key) cf.dx[key] = fenics.Measure("dx", domain=self.mesh, subdomain_data=cf.markers[key]) xdmffile.close() return cf
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 set_boundaries(self): self.boundaries = fe.MeshFunction("size_t", self.mesh, self.mesh.topology().dim() - 1) self.boundaries.set_all(0) self.ds = fe.Measure("ds")(subdomain_data=self.boundaries) self.I = fe.Identity(self.mesh.topology().dim()) self.normal = fe.FacetNormal(self.mesh)
def useSternLayerCellBC(self): """ Interfaces at left hand side and right hand side, species-wise number conservation within interval.""" self.boundary_conditions = [] # Introduce a Lagrange multiplier per species anderson # rebuild discretization scheme (function spaces) self.constraints = 0 self.K = self.M self.discretize() # Potential Dirichlet BC self.u0 = self.delta_u_scaled / 2. self.u1 = -self.delta_u_scaled / 2. boundary_markers = fn.MeshFunction('size_t', self.mesh, self.mesh.topology().dim() - 1) bx = [ Boundary(x0=self.x0_scaled, tol=self.bctol), Boundary(x0=self.x1_scaled, tol=self.bctol) ] # Boundary.mark crashes the kernel if Boundary is internal class for i, b in enumerate(bx): b.mark(boundary_markers, i) boundary_conditions = { 0: { 'Robin': (1. / self.lambda_S_scaled, self.u0) }, 1: { 'Robin': (1. / self.lambda_S_scaled, self.u1) }, } ds = fn.Measure('ds', domain=self.mesh, subdomain_data=boundary_markers) integrals_R = [] for i in boundary_conditions: if 'Robin' in boundary_conditions[i]: r, s = boundary_conditions[i]['Robin'] integrals_R.append(r * (self.u - s) * self.v * ds(i)) self.constraints += sum(integrals_R) # Number conservation constraints N0 = self.L_scaled * self.c_scaled # total amount of species in cell for k in range(self.M): self.logger.info('{:>{lwidth}s} N0 = {:<8.4g}'.format( 'Ion species {:02d} number conservation constraint'.format(k), N0[k], lwidth=self.label_width)) self.applyNumberConservationConstraint(k, self.c_scaled[k])
def mark_boundaries(self, mesh: fenics.mesh): self.value = fenics.MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0) self.value.set_all(IDLE_MARKER) for boundary_name in self.boundary_names: boundary = self.boundary_definition_constructor( self.tolerance, self.boundary_definition_settings[boundary_name]) boundary.mark(self.value, boundary_name.value)
def build_mesh(self): self.length = 8. self.height = 2. self.notch_length = 0.2 self.notch_height = 0.4 domain = mshr.Polygon([fe.Point(0., 0.), fe.Point(self.length/2. - self.notch_length/2., 0.), fe.Point(self.length/2., self.notch_height), fe.Point(self.length/2. + self.notch_length/2., 0.), fe.Point(self.length, 0.), fe.Point(self.length, self.height), fe.Point(self.length/2. + self.notch_length/2., self.height), fe.Point(self.length/2., self.height), fe.Point(self.length/2. - self.notch_length/2., self.height), fe.Point(0., self.height)]) # resolution = 100 if self.local_refinement_iteration == 0 else 200 # self.mesh = mshr.generate_mesh(domain, resolution) self.mesh = mshr.generate_mesh(domain, 100) for i in range(self.local_refinement_iteration): cell_markers = fe.MeshFunction('bool', self.mesh, self.mesh.topology().dim()) cell_markers.set_all(False) for cell in fe.cells(self.mesh): p = cell.midpoint() if p[0] > 14./32.*self.length and p[0] < 18./32.*self.length and p[1] < self.height - self.notch_height: cell_markers[cell] = True self.mesh = fe.refine(self.mesh, cell_markers) length = self.length height = self.height notch_length = self.notch_length class Upper(fe.SubDomain): def inside(self, x, on_boundary): # return on_boundary return on_boundary and fe.near(x[1], height) class LeftCorner(fe.SubDomain): def inside(self, x, on_boundary): return fe.near(x[0], 0.) and fe.near(x[1], 0.) class RightCorner(fe.SubDomain): def inside(self, x, on_boundary): return fe.near(x[0], length) and fe.near(x[1], 0.) class MiddlePoint(fe.SubDomain): def inside(self, x, on_boundary): # return fe.near(x[0], length/2.) and fe.near(x[1], height) return x[0] > length/2. - notch_length/2. and x[0] < length/2. + notch_length/2. and fe.near(x[1], height) self.upper = Upper() self.left = LeftCorner() self.right = RightCorner() self.middle = MiddlePoint()
def adapt_coarse_solution_to_fine_solution(scalar, coarse_solution, fine_solution, element, absolute_tolerance=1.e-2, maximum_refinement_cycles=6, circumradius_threshold=0.01): """ Refine the mesh of the coarse solution until the interpolation error tolerance is met. """ adapted_coarse_mesh = fenics.Mesh(coarse_solution.function_space().mesh()) adapted_coarse_function_space = fenics.FunctionSpace( adapted_coarse_mesh, element) adapted_coarse_solution = fenics.Function(adapted_coarse_function_space) adapted_coarse_solution.leaf_node().vector( )[:] = coarse_solution.leaf_node().vector() for refinement_cycle in range(maximum_refinement_cycles): cell_markers = fenics.MeshFunction( "bool", adapted_coarse_mesh.leaf_node(), adapted_coarse_mesh.topology().dim(), False) for coarse_cell in fenics.cells(adapted_coarse_mesh.leaf_node()): coarse_value = scalar(adapted_coarse_solution.leaf_node(), coarse_cell.midpoint()) fine_value = scalar(fine_solution.leaf_node(), coarse_cell.midpoint()) if (abs(coarse_value - fine_value) > absolute_tolerance): cell_markers[coarse_cell] = True cell_markers = unmark_cells_below_circumradius( adapted_coarse_mesh.leaf_node(), cell_markers, circumradius_threshold) if any(cell_markers): adapted_coarse_mesh = fenics.refine(adapted_coarse_mesh, cell_markers) adapted_coarse_function_space = fenics.FunctionSpace( adapted_coarse_mesh, element) adapted_coarse_solution = fenics.project( fine_solution.leaf_node(), adapted_coarse_function_space.leaf_node()) else: break return adapted_coarse_solution, adapted_coarse_function_space, adapted_coarse_mesh
def test_formulation_1_extrap_1_material(): ''' Test function formulation() with 1 extrinsic trap and 1 material ''' dt = 1 traps = [{ "energy": 1, "materials": [1], "type": "extrinsic" }] materials = [{ "alpha": 1, "beta": 2, "density": 3, "borders": [0, 1], "E_diff": 4, "D_0": 5, "id": 1 }] mesh = fenics.UnitIntervalMesh(10) V = fenics.VectorFunctionSpace(mesh, 'P', 1, 2) W = fenics.FunctionSpace(mesh, 'P', 1) u = fenics.Function(V) u_n = fenics.Function(V) v = fenics.TestFunction(V) n = fenics.interpolate(fenics.Expression('1', degree=0), W) solutions = list(fenics.split(u)) previous_solutions = list(fenics.split(u_n)) testfunctions = list(fenics.split(v)) extrinsic_traps = [n] mf = fenics.MeshFunction('size_t', mesh, 1, 1) dx = fenics.dx(subdomain_data=mf) temp = fenics.Expression("300", degree=0) flux_ = fenics.Expression("10000", degree=0) F, expressions = FESTIM.formulation( traps, extrinsic_traps, solutions, testfunctions, previous_solutions, dt, dx, materials, temp, flux_) expected_form = ((solutions[0] - previous_solutions[0]) / dt) * \ testfunctions[0]*dx expected_form += 5 * fenics.exp(-4/8.6e-5/temp) * \ fenics.dot( fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(1) expected_form += -flux_*testfunctions[0]*dx + \ ((solutions[1] - previous_solutions[1]) / dt) * \ testfunctions[1]*dx expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \ solutions[0] * (extrinsic_traps[0] - solutions[1]) * \ testfunctions[1]*dx(1) expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \ testfunctions[1]*dx(1) expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \ testfunctions[0]*dx assert expected_form.equals(F) is True
def coarsen(self): """ Remesh and refine the new mesh until the interpolation error tolerance is met. For simplicity, for now we'll consider only one scalar component of the solution. """ time = 0. + self.old_state.time fine_solution = self.state.solution.copy(deepcopy=True) self.setup_coarse_mesh() for refinement_cycle in range( self.coarsening_maximum_refinement_cycles): self.setup_function_space() self.setup_states() self.old_state.time = 0. + time self.old_state.solution = fenics.project( fine_solution.leaf_node(), self.function_space.leaf_node()) if refinement_cycle == self.coarsening_maximum_refinement_cycles: break exceeds_tolerance = fenics.MeshFunction("bool", self.mesh.leaf_node(), self.mesh.topology().dim(), False) exceeds_tolerance.set_all(False) for cell in fenics.cells(self.mesh.leaf_node()): coarse_value = self.old_state.solution.leaf_node()(cell.midpoint())\ [self.coarsening_scalar_solution_component_index] fine_value = fine_solution.leaf_node()(cell.midpoint())\ [self.coarsening_scalar_solution_component_index] if (abs(coarse_value - fine_value) > self.coarsening_absolute_tolerance): exceeds_tolerance[cell] = True if any(exceeds_tolerance): self.mesh = fenics.refine(self.mesh, exceeds_tolerance) else: break self.setup_problem_and_solver() # We broke important references.
def eva(self): # construct solutions corresponding to the basis functions class BoundaryX0(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[0], 0.0) class BoundaryX1(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[0], 1.0) class BoundaryY0(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[1], 0.0) class BoundaryY1(fe.SubDomain): def inside(self, x, on_boundary): return on_boundary and fe.near(x[1], 1.0) boundaries = fe.MeshFunction('size_t', self.mesh, self.mesh.topology().dim() - 1) boundaries.set_all(0) bc0, bc1, bc2, bc3 = BoundaryX0(), BoundaryX1(), BoundaryY0( ), BoundaryY1() bc0.mark(boundaries, 1) bc1.mark(boundaries, 2) bc2.mark(boundaries, 3) bc3.mark(boundaries, 4) domains = fe.MeshFunction("size_t", self.mesh, self.mesh.topology().dim()) domains.set_all(0) dx = fe.Measure('dx', domain=self.mesh, subdomain_data=domains) ds = fe.Measure('ds', domain=self.mesh, subdomain_data=boundaries) u_trial, u_test = fe.TrialFunction(self.Vu), fe.TestFunction(self.Vu) left = fe.inner(fe.nabla_grad(u_trial), fe.nabla_grad(u_test)) * dx right = self.f * u_test * dx + (self.q1 * u_test * ds(1) + self.q2 * u_test * ds(2) + self.q3 * u_test * ds(3)) bcD = fe.DirichletBC(self.Vu, self.theta, boundaries, 4) left_m, right_m = fe.assemble_system(left, right, bcD) fe.solve(left_m, self.u.vector(), right_m)
def refine_mesh(self, tolerance: float) -> Optional[bool]: """Generate refined mesh. This method locates cells of the mesh where the error of the eigenfunction is above a certain threshold and generates a new mesh with finer resolution on the problematic regions. For a given eigenfunction $u$ with corresponding eigenvalue $\lambda$, it must be true that $a(u, v) = \lambda b(u, v)$ for all functions $v$. We make $v$ go through all the basis functions on the mesh and locate the cells where the previous identity fails to hold. Parameters ---------- tolerance : float Criterion to determine whether a cell needs to be refined or not. Returns ------- refined_mesh : Optional[fenics.Mesh] A new mesh derived from `mesh` with higher level of granularity on certain regions. If no refinements are needed, None is returned. """ ew, ev = self.eigenvalues[1:], self.eigenfunctions[1:] dofs_needing_refinement = set() # Find all the degrees of freedom needing refinement. for k, (l, u) in enumerate(zip(ew, ev)): v = fenics.TrialFunction(self.vector_space) a, b = self._construct_eigenproblem(u, v) A = fenics.assemble(a * fenics.dx) B = fenics.assemble(b * fenics.dx) error = np.abs((A - l * B).sum()) indices = np.flatnonzero(error > tolerance) dofs_needing_refinement.update(indices) if not dofs_needing_refinement: return # Refine the cells corresponding to the degrees of freedom needing # refinement. dofmap = self.vector_space.dofmap() cell_markers = fenics.MeshFunction('bool', self.mesh, self.mesh.topology().dim()) cell_markers.set_all(False) for cell in fenics.cells(self.mesh): cell_dofs = set(dofmap.cell_dofs(cell.index())) if cell_dofs.intersection(dofs_needing_refinement): cell_markers[cell] = True return fenics.refine(self.mesh, cell_markers)
def preprocess(fname): """Loads mesh, defines system of equations and prepares system matrix.""" mesh = fe.Mesh(fname + ".xml") if INPUTS['saving']['mesh']: fe.File(fname + "_mesh.pvd") << mesh boundaries = fe.MeshFunction('size_t', mesh, fname + '_facet_region.xml') if INPUTS['saving']['boundaries']: fe.File(fname + "_subdomains.pvd") << boundaries subdomains = fe.MeshFunction('size_t', mesh, fname + '_physical_region.xml') if INPUTS['saving']['subdomains']: fe.File(fname + "_subdomains.pvd") << subdomains if INPUTS['plotting']['mesh']: fe.plot(mesh, title='Mesh') if INPUTS['plotting']['boundaries']: fe.plot(boundaries, title='Boundaries') if INPUTS['plotting']['subdomains']: fe.plot(subdomains, title='Subdomains') fun_space = fe.FunctionSpace(mesh, INPUTS['element_type'], INPUTS['element_degree'], constrained_domain=PeriodicDomain()) if ARGS['--verbose']: dofmap = fun_space.dofmap() print('Number of DOFs:', len(dofmap.dofs())) field = fe.TrialFunction(fun_space) test_func = fe.TestFunction(fun_space) cond = Conductivity(subdomains, fe.Constant(INPUTS['conductivity']['gas']), fe.Constant(INPUTS['conductivity']['solid']), degree=0) system_matrix = -cond * fe.inner(fe.grad(field), fe.grad(test_func)) * fe.dx bctop = fe.Constant(INPUTS['boundary_conditions']['top']) bcbot = fe.Constant(INPUTS['boundary_conditions']['bottom']) bcs = [ fe.DirichletBC(fun_space, bctop, boundaries, 1), fe.DirichletBC(fun_space, bcbot, boundaries, 2) ] field = fe.Function(fun_space) return system_matrix, field, bcs, cond
def BCsDefinition(Dimensions, Mesh, V, u_0, u_1, LoadCase, BCsType=False): # Define geometric spaces class LowerSide(fe.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and fe.near(x[2], -Dimensions[2] / 2, tol) class UpperSide(fe.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and fe.near(x[2], Dimensions[2] / 2, tol) # Define integration over subdpmains Domains_Facets = fe.MeshFunction('size_t', Mesh, Mesh.geometric_dimension() - 1) ds = fe.Measure('ds', domain=Mesh, subdomain_data=Domains_Facets) # Mark all domain facets with 0 Domains_Facets.set_all(0) # Mark bottom facets with 1 bottom = LowerSide() bottom.mark(Domains_Facets, 1) # Mark upper facets with 2 upper = UpperSide() upper.mark(Domains_Facets, 2) # Apply boundary conditions if BCsType == 'Ideal': if LoadCase == 'SimpleShear': bcl = fe.DirichletBC(V, u_0, Domains_Facets, 1) bcu = fe.DirichletBC(V, u_1, Domains_Facets, 2) else: bcl = fe.DirichletBC(V.sub(2), u_0, Domains_Facets, 1) bcu = fe.DirichletBC(V.sub(2), u_1, Domains_Facets, 2) else: bcl = fe.DirichletBC(V, u_0, Domains_Facets, 1) bcu = fe.DirichletBC(V, u_1, Domains_Facets, 2) # Set of boundary conditions BoundaryConditions = [bcl, bcu] return [BoundaryConditions, ds]
def initial_mesh(self): mesh = self.coarse_mesh() for cycle in range(self.initial_hot_wall_refinement_cycles): edge_markers = fenics.MeshFunction("bool", mesh, 1, False) self.hot_wall.mark(edge_markers, True) fenics.adapt(mesh, edge_markers) mesh = mesh.child() return mesh
def get_boundaries(self): """ Load the boundaries data of the mesh. More specifically, this method loads the facet_region.xml file generated by the dolfin-converter. Returns: """ if self.boundaries is None: bound_name = self.filename.split('.')[0] + '_facet_region.xml' file = self.mesh_folder_path + '/' + bound_name self.boundaries = fn.MeshFunction('size_t', self.mesh, file) if self.boundaries_ids is None: self.boundaries_ids, _ = GMSHInterface.get_boundaries_ids( self.geo_file)
def readFacetFunction(self, group_value_dict, *args, **kwargs): """ Reads facet function and returns it. """ self.readMesh() xdmffile = fenics.XDMFFile(self.xdmffilename) ff = FacetFunctionFromXDMF(group_value_dict, *args, **kwargs) ff.init() for (key, value) in ff.group_value_dict.items(): ff.markers[key] = fenics.MeshFunction("size_t", self.mesh, self.mesh.topology().dim() - 1) xdmffile.read(ff.markers[key], key) ff.marked[key] = value.get("marked", 1) ff.ds[key] = fenics.Measure("ds", domain=self.mesh, subdomain_data=ff.markers[key]) ff.bcs[key] = value xdmffile.close() return ff
def wrapper2D(par, meshName, N_PN, boundaryFilePrefix, solutionFolder): #-------- load mesh -------- mesh = fe.Mesh(meshName + '.xml') boundaryMarkers = fe.MeshFunction('size_t', mesh, meshName + '_facet_region.xml') ds = fe.Measure('ds', domain=mesh, subdomain_data=boundaryMarkers) u = solvePN2nd(par, N_PN, mesh, boundaryFilePrefix, ds) #fe.plot(u[0]) # first moment: u0 = int_{4pi} I * b0 dOmega, b0 = sqrt(1 / 4 / pi) # radiative energy: phi = int_{4pi} I dOmega radiativeEnergy = np.sqrt(4 * np.pi) * u[0].compute_vertex_values() createFolder(solutionFolder) sio.savemat('%sradiativeEnergy_P%d2nd_%s.mat'%(solutionFolder, N_PN, meshName.split('/')[-1]), {'radiativeEnergy': radiativeEnergy, 'points': mesh.coordinates(), 'connectivityList': mesh.cells()}) return u
def refine_initial_mesh(self): """ Refine near the hot wall. """ class HotWall(fenics.SubDomain): def inside(self, x, on_boundary): return on_boundary and fenics.near(x[0], 0.) hot_wall = HotWall() for i in range(self.initial_hot_wall_refinement_cycles): edge_markers = fenics.MeshFunction("bool", self.mesh, 1, False) hot_wall.mark(edge_markers, True) fenics.adapt(self.mesh, edge_markers) self.mesh = self.mesh.child()
def bottom_wall_shear_integrand(self): nhat = fenics.FacetNormal(self.mesh) p, u, T, C = fenics.split(self.solution) bottom_wall_id = 2 mesh_function = fenics.MeshFunction("size_t", self.mesh, self.mesh.topology().dim() - 1) self.bottom_wall.mark(mesh_function, bottom_wall_id) dot, grad = fenics.dot, fenics.grad ds = fenics.ds(domain=self.mesh, subdomain_data=mesh_function, subdomain_id=bottom_wall_id) return dot(grad(u[0]), nhat) * ds
def refine_initial_mesh(self): """ Refine near the phase-change interface. """ y_pci = self.y_pci class PhaseInterface(fenics.SubDomain): def inside(self, x, on_boundary): return fenics.near(x[1], y_pci) phase_interface = PhaseInterface() for i in range(self.pci_refinement_cycles): edge_markers = fenics.MeshFunction("bool", self.mesh, 1, False) phase_interface.mark(edge_markers, True) fenics.adapt(self.mesh, edge_markers) self.mesh = self.mesh.child( ) # Does this break references? Can we do this a different way?
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 _build_function_space(self): class Exterior(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary self.exterior = Exterior() self.V = fa.FunctionSpace(self.mesh, 'P', 1) self.sub_domains = fa.MeshFunction("size_t", self.mesh, self.mesh.topology().dim() - 1) self.sub_domains.set_all(0) self.normal = fa.FacetNormal(self.mesh) self.ds = fa.Measure("ds")(subdomain_data=self.sub_domains) # self.source = fa.Expression(("cos(pi*x[0])*cos(pi*x[1])"), degree=3) self.source = fa.Expression(("x[0]*x[0] + x[1]*x[1]"), degree=3) self.source = fa.interpolate(self.source, self.V) # self.source = fa.Constant(1.) self.bcs = [] boundary_fn = fa.Constant(0.) boundary_bc = fa.DirichletBC(self.V, boundary_fn, self.exterior) self.bcs = self.bcs + [boundary_bc]
def defineBoundaryMarkers1D(mesh, zMin, zMax): """For implementation details, see https://fenicsproject.org/olddocs/dolfin/1.3.0/python/demo/documented/subdomains-poisson/python/documentation.html https://fenicsproject.discourse.group/t/natural-boundary-conditions-without-facetfunction/228/3 """ boundaries = fe.MeshFunction("size_t", mesh, mesh.topology().dim() - 1) class Left(fe.SubDomain): def inside(self, x, on_boundary): return fe.near(x[0], zMin) class Right(fe.SubDomain): def inside(self, x, on_boundary): return fe.near(x[0], zMax) left = Left() right = Right() left.mark(boundaries, 1) right.mark(boundaries, 2) ds = fe.Measure("ds", domain=mesh, subdomain_data=boundaries) return ds
def load_2d_muscle_geo(filename='../geo/muscle_2d.xml', L0=1e-2): mesh = fe.Mesh(filename) coords = mesh.coordinates() coords *= L0 mesh.bounding_box_tree().build(mesh) # Define Boundaries bottom = fe.CompiledSubDomain("near(x[1], side, 0.01) && on_boundary", side=-20.0 * L0) top = fe.CompiledSubDomain("near(x[1], side, 0.01) && on_boundary", side=20.0 * L0) # Initialize mesh function for boundary domains boundaries = fe.MeshFunction('size_t', mesh, 2) boundaries.set_all(0) bottom.mark(boundaries, 1) top.mark(boundaries, 2) # Define new measures associated with the interior domains and # exterior boundaries dx = fe.Measure('dx', domain=mesh) ds = fe.Measure('ds', domain=mesh, subdomain_data=boundaries) return mesh, dx, ds, {"top": top, "bottom": bottom}