def set_basis(order, basis_name): ''' Sets the basis class given the basis_name string argument Inputs: ------- order: solution order basis_name: name of the basis function we wish to instantiate as a class Outputs: -------- basis: instantiated basis class Raise: ------ If the basis class is not defined, returns a NotImplementedError ''' if BasisType[basis_name] == BasisType.LagrangeSeg: basis = basis_defs.LagrangeSeg(order) elif BasisType[basis_name] == BasisType.LegendreSeg: basis = basis_defs.LegendreSeg(order) elif BasisType[basis_name] == BasisType.LagrangeQuad: basis = basis_defs.LagrangeQuad(order) elif BasisType[basis_name] == BasisType.LegendreQuad: basis = basis_defs.LegendreQuad(order) elif BasisType[basis_name] == BasisType.LagrangeTri: basis = basis_defs.LagrangeTri(order) elif BasisType[basis_name] == BasisType.HierarchicH1Tri: basis = basis_defs.HierarchicH1Tri(order) else: raise NotImplementedError return basis
def set_basis_spacetime(mesh, order, basis_name): ''' Sets the space-time basis class given the basis_name string argument Inputs: ------- order: solution order basis_name: name of the spatial basis function used to determine the space-time basis function we wish to instantiate as a class Outputs: -------- basis_st: instantiated space-time basis class Raise: ------ If the basis class is not defined returns a NotImplementedError ''' if BasisType[basis_name] == BasisType.LagrangeSeg: basis_st = basis_defs.LagrangeQuad(order) elif BasisType[basis_name] == BasisType.LegendreSeg: basis_st = basis_defs.LegendreQuad(order) elif BasisType[basis_name] == BasisType.LagrangeQuad: basis_st = basis_defs.LagrangeHex(order) elif BasisType[basis_name] == BasisType.LagrangeTri: basis_st = basis_defs.LagrangePrism(order) else: raise NotImplementedError return basis_st
import numerics.basis.basis as basis_defs import numerics.basis.tools as basis_tools import processing.plot as plot ''' Parameters ''' p = 3 # polynomial order b = 10 # the (b+1)th basis function will be plotted # Node type (matters for nodal basis only) node_type = "Equidistant" # node_type = "GaussLobatto" # Basis type basis = basis_defs.LagrangeQuad(p) # Lagrange basis # basis = basis_defs.LegendreQuad(p) # Legendre basis ''' Pre-processing ''' # Solution nodes basis.get_1d_nodes = basis_tools.set_1D_node_calc(node_type) # Sample points n = 101 # number of points in each direction x = y = np.linspace(-1., 1., n) X, Y = np.meshgrid(x, y) xp = np.array([np.reshape(X, -1), np.reshape(Y, -1)]).transpose() ntot = n**2 # total number of points ''' Evaluate
def create_gmsh_element_database(): ''' This function creates a database that holds information about all supported Gmsh elements. Outputs: -------- gmsh_element_database: Gmsh element database ''' gmsh_element_database = {} ''' Assume most element types are not supported Only fill in supported elements ''' # Point etype_num = 15 elem_data = GmshElementData() gmsh_element_database.update({etype_num: elem_data}) elem_data.gorder = 0 elem_data.gbasis = basis_defs.PointShape() # shape here instead of gbasis elem_data.num_nodes = 1 elem_data.node_order = np.array([0]) # Line segments (q = 1 to q = 11) etype_nums = np.array([1, 8, 26, 27, 28, 62, 63, 64, 65, 66]) for i in range(etype_nums.shape[0]): etype_num = etype_nums[i] elem_data = GmshElementData() gmsh_element_database.update({etype_num: elem_data}) gorder = i + 1 elem_data.gorder = gorder elem_data.gbasis = basis_defs.LagrangeSeg(gorder) elem_data.num_nodes = gorder + 1 elem_data.node_order = gmsh_node_order_seg(gorder) # Triangles (q = 1 to q = 10) etype_nums = np.array([2, 9, 21, 23, 25, 42, 43, 44, 45, 46]) for i in range(etype_nums.shape[0]): etype_num = etype_nums[i] elem_data = GmshElementData() gmsh_element_database.update({etype_num: elem_data}) gorder = i + 1 elem_data.gorder = gorder elem_data.gbasis = basis_defs.LagrangeTri(gorder) elem_data.num_nodes = (gorder + 1) * (gorder + 2) // 2 elem_data.node_order = gmsh_node_order_tri(gorder) # Quadrilaterals (q = 1 to q = 11) etype_nums = np.array([3, 10, 36, 37, 38, 47, 48, 49, 50, 51]) for i in range(etype_nums.shape[0]): etype_num = etype_nums[i] elem_data = GmshElementData() gmsh_element_database.update({etype_num: elem_data}) gorder = i + 1 elem_data.gorder = gorder elem_data.gbasis = basis_defs.LagrangeQuad(gorder) elem_data.num_nodes = (gorder + 1)**2 elem_data.node_order = gmsh_node_order_quadril(gorder) return gmsh_element_database
def mesh_2D(num_elems_x=10, num_elems_y=10, xmin=-1., xmax=1., ymin=-1., ymax=1.): ''' This function creates a uniform 2D quadrilateral mesh. Inputs: ------- num_elems_x: number of elements in x-direction num_elems_y: number of elements in y-direction xmin: minimum x-coordinate xmax: maximum x-coordinate ymin: minimum y-coordinate ymax: maximum y-coordinate Outputs: -------- mesh: mesh object Notes: ------ Four boundary groups are created: x1: located along the line x = xmin x2: located along the line x = xmax y1: located along the line y = ymin y2: located along the line y = ymax ''' ''' Create mesh and set node coordinates ''' # Number of nodes num_nodes_x = num_elems_x + 1 num_nodes_y = num_elems_y + 1 # xy-coordinates xcoords = np.linspace(xmin, xmax, num_nodes_x) ycoords = np.linspace(ymin, ymax, num_nodes_y) xgrid, ygrid = np.meshgrid(xcoords, ycoords) xp = np.array([np.reshape(xgrid, -1), np.reshape(ygrid, -1)]).transpose() # Create mesh mesh = mesh_defs.Mesh(ndims=2, num_nodes=xp.shape[0], num_elems=num_elems_x * num_elems_y, gbasis=basis_defs.LagrangeQuad(1), gorder=1) # Store coordinates mesh.node_coords = xp ''' Interior faces ''' # Number of interior faces mesh.num_interior_faces = num_elems_y*(num_elems_x-1) + \ num_elems_x*(num_elems_y-1) mesh.allocate_interior_faces() # x-direction n = 0 for ny in range(num_elems_y): for nx in range(num_elems_x - 1): interior_face = mesh.interior_faces[n] interior_face.elemL_ID = num_elems_x * ny + nx interior_face.faceL_ID = 1 interior_face.elemR_ID = num_elems_x * ny + nx + 1 interior_face.faceR_ID = 3 n += 1 # y-direction for nx in range(num_elems_x): for ny in range(num_elems_y - 1): interior_face = mesh.interior_faces[n] interior_face.elemL_ID = num_elems_x * ny + nx interior_face.faceL_ID = 2 interior_face.elemR_ID = num_elems_x * (ny + 1) + nx interior_face.faceR_ID = 0 n += 1 ''' Boundary groups and faces ''' # x1 boundary_group = mesh.add_boundary_group("x1") boundary_group.num_boundary_faces = num_elems_y boundary_group.allocate_boundary_faces() n = 0 for boundary_face in boundary_group.boundary_faces: boundary_face.elem_ID = num_elems_x * n boundary_face.face_ID = 3 n += 1 # x2 boundary_group = mesh.add_boundary_group("x2") boundary_group.num_boundary_faces = num_elems_y boundary_group.allocate_boundary_faces() n = 0 for boundary_face in boundary_group.boundary_faces: boundary_face.elem_ID = num_elems_x * (n + 1) - 1 boundary_face.face_ID = 1 n += 1 # y1 boundary_group = mesh.add_boundary_group("y1") boundary_group.num_boundary_faces = num_elems_x boundary_group.allocate_boundary_faces() n = 0 for boundary_face in boundary_group.boundary_faces: boundary_face.elem_ID = n boundary_face.face_ID = 0 n += 1 # y2 boundary_group = mesh.add_boundary_group("y2") boundary_group.num_boundary_faces = num_elems_x boundary_group.allocate_boundary_faces() n = 0 for boundary_face in boundary_group.boundary_faces: boundary_face.elem_ID = mesh.num_elems - num_elems_x + n boundary_face.face_ID = 2 n += 1 ''' Create element-to-node-ID map ''' mesh.allocate_elem_to_node_IDs_map() elem = 0 for ny in range(num_elems_y): for nx in range(num_elems_x): mesh.elem_to_node_IDs[elem][0] = num_nodes_x * ny + nx mesh.elem_to_node_IDs[elem][1] = num_nodes_x * ny + nx + 1 mesh.elem_to_node_IDs[elem][2] = num_nodes_x * (ny + 1) + nx mesh.elem_to_node_IDs[elem][3] = num_nodes_x * (ny + 1) + nx + 1 elem += 1 ''' Create element objects ''' mesh.create_elements() return mesh