def test_get_faces_to_elems(): mesh1d_uniform = mesh.Mesh1DUniform(0.0, 1.0, 10) mesh2d_cartesian = mesh.Mesh2DCartesian(0.0, 1.0, 0.0, 1.0, 10, 10) mesh2d_unstructured = mesh.Mesh2DUnstructuredRectangle( 0.0, 1.0, 0.0, 1.0, 10, 10) mesh_array = [mesh1d_uniform, mesh2d_cartesian, mesh2d_unstructured] for mesh_ in mesh_array: faces_to_elems = mesh_._get_faces_to_elems(mesh_.faces, mesh_.elems, mesh_.boundary_faces) for i_face in range(mesh_.num_faces): for i_elem in faces_to_elems[i_face]: assert math_utils.isin(i_elem, mesh_.face_to_elems[i_face])
def test_get_elems_to_faces(): mesh1d_uniform = mesh.Mesh1DUniform(0.0, 1.0, 10) mesh2d_cartesian = mesh.Mesh2DCartesian(0.0, 1.0, 0.0, 1.0, 10, 10) mesh2d_unstructured = mesh.Mesh2DUnstructuredRectangle( 0.0, 1.0, 0.0, 1.0, 10, 10) mesh_array = [mesh1d_uniform, mesh2d_cartesian, mesh2d_unstructured] for mesh_ in mesh_array: elems_to_faces = mesh_._get_elems_to_faces(mesh_.faces, mesh_.elems, mesh_.num_faces_per_elem) for i_elem in range(mesh_.num_elems): for i_face in elems_to_faces[i_elem]: assert math_utils.isin(i_face, mesh_.elems_to_faces[i_elem])
def get_solution_on_face(self, dg_solution, face_index, x, t): mesh_ = dg_solution.mesh_ assert math_utils.isin(face_index, mesh_.boundary_faces) left_elem_index = mesh_.faces_to_elems[face_index, 0] right_elem_index = mesh_.faces_to_elems[face_index, 1] if left_elem_index != -1: interior_state = dg_solution.evaluate_canonical( 1.0, left_elem_index) else: interior_state = dg_solution.evaluate_canonical( -1.0, right_elem_index) return (interior_state, interior_state)
def get_left_right_states(self, dg_solution, face_index, x, t): mesh_ = dg_solution.mesh_ # Need to extrapolate based on average value assert math_utils.isin(face_index, mesh_.boundary_faces) elem_indices = mesh_.faces_to_elems[face_index] if elem_indices[0] == -1: elem_index = elem_indices[1] else: elem_index = elem_indices[0] left_state = dg_solution(x, elem_index) right_state = dg_solution(x, elem_index) return (left_state, right_state)
def get_left_right_states(self, dg_solution, face_index, x, t): mesh_ = dg_solution.mesh_ assert math_utils.isin(face_index, mesh_.boundary_faces) if mesh_.num_dims == 1: # determine which elements are on boundary rightmost_elem = mesh_.get_rightmost_elem_index() leftmost_elem = mesh_.get_leftmost_elem_index() # left state is right side of rightmost elem left_state = dg_solution.evaluate_canonical( np.array([1.0]), rightmost_elem) # right state is left side of leftmost elem right_state = dg_solution.evaluate_canonical( np.array([-1.0]), leftmost_elem) else: # assume Mesh2DCartesian if x[0] == mesh_.x_left: right_elem_index = mesh_.faces_to_elems[face_index, 1] tuple_ = mesh_.to_row_col_indices(right_elem_index) left_elem_index = mesh_.from_row_col_indices( tuple_[0], mesh_.num_cols - 1) elif x[0] == mesh_.x_right: left_elem_index = mesh_.faces_to_elems[face_index, 0] tuple_ = mesh_.to_row_col_indices(left_elem_index) right_elem_index = mesh_.from_row_col_indices(tuple_[0], 0) elif x[1] == mesh_.y_bottom: right_elem_index = mesh_.faces_to_elems[face_index, 1] tuple_ = mesh_.to_row_col_indices(right_elem_index) left_elem_index = mesh_.from_row_col_indices( mesh_.num_rows - 1, tuple_[1]) elif x[1] == mesh_.y_top: left_elem_index = mesh_.faces_to_elems[face_index, 0] tuple_ = mesh_.to_row_col_indices(left_elem_index) right_elem_index = mesh_.from_row_col_indices(0, tuple_[1]) right_state = dg_solution(x, right_elem_index) left_state = dg_solution(x, left_elem_index) return (left_state, right_state)
def evaluate_boundary_matrix(self, mesh_, basis_, face_index, riemann_solver, t, matrix, vector): assert math_utils.isin(face_index, mesh_.boundary_faces) elems = mesh_.faces_to_elems[face_index] x = mesh_.get_face_position(face_index) tuple_ = riemann_solver.linear_constants(x, t) c_l = tuple_[0] c_r = tuple_[1] phi_p1 = basis_.phi_p1 phi_m1 = basis_.phi_m1 # left boundary if elems[0] == -1: # Q_{i-1} should be Q_i # replacing rightmost state of Q_{i-1} with leftmost state of Q_i # normally we have 1/m_i c_l_imh Cm11 Q_{i-1} in interior # on boundary 1/m_i c_l_imh Cm1m1 Q_i i = elems[1] indices_i = solution.vector_indices(i, basis_.num_basis_cpts) Cm1m1 = np.matmul(basis_.mass_matrix_inverse, np.outer(phi_m1, phi_m1)) matrix[indices_i, indices_i] += (1.0 / mesh_.elem_metrics[i]) * c_l * Cm1m1 # right boundary elif elems[1] == -1: # Q_{i+1} should be Q_i # replacing leftmost state of Q_{i+1} with rightmost state of Q_i # normally we have -1/m_i c_r_imh C1m1 Q_{i+1} in interior # on boundary -1/m_i c_r_imh C11 Q_i i = elems[0] indices_i = solution.vector_indices(i, basis_.num_basis_cpts) C11 = np.matmul(basis_.mass_matrix_inverse, np.outer(phi_p1, phi_p1)) matrix[indices_i, indices_i] += (-1.0 / mesh_.elem_metrics[i]) * c_r * C11 return (matrix, vector)
def evaluate_boundary_matrix(self, mesh_, basis_, face_index, riemann_solver, t, matrix, vector): assert math_utils.isin(face_index, mesh_.boundary_faces) elems = mesh_.faces_to_elems[face_index] x = mesh_.get_face_position(face_index) tuple_ = riemann_solver.linear_constants(x, t) c_l = tuple_[0] c_r = tuple_[1] phi_p1 = basis_.phi_p1 phi_m1 = basis_.phi_m1 # left boundary if elems[0] == -1: # Q_{i-1} should be rightmost elem i = elems[1] indices_i = solution.vector_indices(i, basis_.num_basis_cpts) indices_l = solution.vector_indices( mesh_.get_rightmost_elem_index(), basis_.num_basis_cpts) Cm11 = np.matmul(basis_.mass_matrix_inverse, np.outer(phi_m1, phi_p1)) matrix[indices_i, indices_l] += (1.0 / mesh_.elem_metrics[i]) * c_l * Cm11 # right boundary elif elems[1] == -1: i = elems[0] indices_i = solution.vector_indices(i, basis_.num_basis_cpts) indices_r = solution.vector_indices( mesh_.get_leftmost_elem_index(), basis_.num_basis_cpts) C1m1 = np.matmul(basis_.mass_matrix_inverse, np.outer(phi_p1, phi_m1)) matrix[indices_i, indices_r] += (-1.0 / mesh_.elem_metrics[i]) * c_r * C1m1 return (matrix, vector)
def test_isin(): x = range(10) assert math_utils.isin(1, x) assert not math_utils.isin(-1, x)