def compute_hybrid_matrices( self, cell: Cell, faces: List[Face], cell_basis_l: Basis, cell_basis_k: Basis, cell_basis_k1: Basis, face_basis_k: Basis, unknown: Unknown, ): """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ # ============================================================================================================== # GRADIENT OPERATOR / STABILIZATION OPERATOR # ============================================================================================================== mat_F_phi_k_phi_l_list = [] mat_F_phi_k_psi_k_list = [] for mface in mfaces: mat_F_phi_k_phi_l = Integration.get_cell_mass_matrix_in_face( mcell.cell, mface.face, cell_basis_k, cell_basis_l) mat_F_phi_k_phi_l_list.append(mat_F_phi_k_phi_l_list) # ---------------------------------------------------------------------------------------------------------- mat_F_phi_k_psi_k = Integration.get_hybrid_mass_matrix_in_face( mcell.cell, mface.face, cell_basis_k, face_basis_k, mface.face.reference_frame_transformation_matrix) mat_F_phi_k_psi_k_list.append(mat_F_phi_k_psi_k) # ============================================================================================================== # RECONSTRUCTION OPERATOR # ============================================================================================================== mat_F_grad_phi_k1_psi_k_list = [] mat_F_grad_phi_k1_phi_l_list = [] for mface in mfaces: mat_F_grad_phi_k1_psi_k_j_list = [] mat_F_grad_phi_k1_phi_l_j_list = [] for j in range(len(unknown.problem_dimension)): # ------------------------------------------------------------------------------------------------------ mat_F_grad_phi_k1_psi_k_j = Integration.get_hybrid_advection_matrix_in_face( mcell.cell, mface.face, cell_basis_k1, face_basis_k, mface.face.reference_frame_transformation_matrix, j, ) mat_F_grad_phi_k1_psi_k_j_list.append( mat_F_grad_phi_k1_psi_k_j) # ------------------------------------------------------------------------------------------------------ mat_F_phi_l_grad_phi_k1_j = Integration.get_cell_advection_matrix_in_face( mcell.cell, mface.face, cell_basis_l, cell_basis_k1, j) # ------------------------------------------------------------------------------------------------------ mat_F_grad_phi_k1_phi_l_j = mat_F_phi_l_grad_phi_k1_j.T mat_F_grad_phi_k1_phi_l_j_list.append( mat_F_grad_phi_k1_phi_l_j) # ---------------------------------------------------------------------------------------------------------- mat_F_grad_phi_k1_psi_k_list.append(mat_F_grad_phi_k1_psi_k_j_list) mat_F_grad_phi_k1_phi_l_list.append(mat_F_grad_phi_k1_phi_l_j_list) # ============================================================================================================== # STABILIZATION OPERATOR # ============================================================================================================== mat_F_psi_k_phi_k1_list = [] for mface in mfaces: mat_F_phi_k1_psi_k = Integration.get_hybrid_mass_matrix_in_face( mcell.cell, mface.face, cell_basis_k1, face_basis_k, mface.face.reference_frame_transformation_matrix) mat_F_psi_k_phi_k1_list.append(mat_F_phi_k1_psi_k) return ( mat_F_phi_k_phi_l_list, mat_F_phi_k_psi_k_list, mat_F_grad_phi_k1_psi_k_list, mat_F_grad_phi_k1_phi_l_list, mat_F_psi_k_phi_k1_list, )
def get_stabilization_operator( self, cell: Cell, faces: List[Face], cell_basis_l: Basis, cell_basis_k: Basis, cell_basis_k1: Basis, face_basis_k: Basis, unknown: Unknown, ) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ # -------------------------------------------------------------------------------------------------------------- # rec # -------------------------------------------------------------------------------------------------------------- local_reconstruction_operator = self.get_local_reconstruction_operator( cell, faces, cell_basis_l, cell_basis_k, cell_basis_k1, face_basis_k, unknown) # -------------------------------------------------------------------------------------------------------------- # Initializing the local stabilization form matrix # -------------------------------------------------------------------------------------------------------------- local_problem_size = self.get_local_problem_size( faces, cell_basis_l, face_basis_k, unknown) local_stabilization_operator = np.zeros( (local_problem_size, local_problem_size)) derivative_directions = range(unknown.problem_dimension) directions = range(unknown.field_dimension) for i in directions: # # ------------------------------------------------------------------------------------------------------ # r0_r = i * cell_basis_k1.basis_dimension # r1_r = (i + 1) * cell_basis_k1.basis_dimension # ------------------------------------------------------------------------------------------------------ c0_c = i * cell_basis_l.basis_dimension c1_c = (i + 1) * cell_basis_l.basis_dimension for f, face in enumerate(faces): passmat = Operator.get_face_passmat(cell, face) # normal_vector_component = passmat[-1, j] # -------------------------------------------------------------------------------------------------- # Getting the indices corresponding to the face_indexth face for the field on the ith axis # -------------------------------------------------------------------------------------------------- c0_f = ( unknown.field_dimension * cell_basis_l.basis_dimension + f * unknown.field_dimension * face_basis_k.basis_dimension + i * face_basis_k.basis_dimension) c1_f = ( unknown.field_dimension * cell_basis_l.basis_dimension + f * unknown.field_dimension * face_basis_k.basis_dimension + (i + 1) * face_basis_k.basis_dimension) # ------------------------------------------------------------------------------------------------------ # Compting matrices 1 # ------------------------------------------------------------------------------------------------------ m_face_id = np.eye(face_basis_k.basis_dimension) m_face_psi_k_psi_k = Integration.get_face_mass_matrix_in_face( face, face_basis_k, face_basis_k, passmat) m_face_psi_k_psi_k_inv = np.linalg.inv(m_face_psi_k_psi_k) # ------------------------------------------------------------------------------------------------------ m_cell_phi_k_phi_k = Integration.get_cell_mass_matrix_in_cell( cell, cell_basis_k, cell_basis_k) m_cell_phi_k_phi_k_inv = np.linalg.inv(m_cell_phi_k_phi_k) m_cell_phi_l_phi_l = Integration.get_cell_mass_matrix_in_cell( cell, cell_basis_l, cell_basis_l) m_cell_phi_l_phi_l_inv = np.linalg.inv(m_cell_phi_l_phi_l) # ------------------------------------------------------------------------------------------------------ # proj T -> F, l -> k # ------------------------------------------------------------------------------------------------------ m_face_phi_l_psi_k = Integration.get_hybrid_mass_matrix_in_face( cell, face, cell_basis_l, face_basis_k, passmat) m_face_psi_k_phi_l = m_face_phi_l_psi_k.T pi_c_f_l_k = m_face_psi_k_psi_k_inv @ m_face_psi_k_phi_l # ------------------------------------------------------------------------------------------------------ # proj T -> F, k -> k # ------------------------------------------------------------------------------------------------------ m_face_phi_k_psi_k = Integration.get_hybrid_mass_matrix_in_face( cell, face, cell_basis_k, face_basis_k, passmat) m_face_psi_k_phi_k = m_face_phi_k_psi_k.T pi_c_f_k_k = m_face_psi_k_psi_k_inv @ m_face_psi_k_phi_k # ------------------------------------------------------------------------------------------------------ # proj T -> F, k1 -> k # ------------------------------------------------------------------------------------------------------ m_face_phi_k1_psi_k = Integration.get_hybrid_mass_matrix_in_face( cell, face, cell_basis_k1, face_basis_k, passmat) m_face_psi_k_phi_k1 = m_face_phi_k1_psi_k.T pi_c_f_k1_k = m_face_psi_k_psi_k_inv @ m_face_psi_k_phi_k1 # ------------------------------------------------------------------------------------------------------ # proj T -> T, k1 -> l # ------------------------------------------------------------------------------------------------------ m_cell_phi_l_phi_k1 = Integration.get_cell_mass_matrix_in_cell( cell, cell_basis_l, cell_basis_k1) pi_c_c_k1_l = m_cell_phi_l_phi_l_inv @ m_cell_phi_l_phi_k1 # ------------------------------------------------------------------------------------------------------ m_stab_face_jump = np.zeros( (face_basis_k.basis_dimension, local_problem_size)) m_stab_face_jump[:, c0_c:c1_c] -= pi_c_f_l_k m_stab_face_jump[:, c0_f:c1_f] += m_face_id # ------------------------------------------------------------------------------------------------------ c0_r = i * cell_basis_k1.basis_dimension c1_r = (i + 1) * cell_basis_k1.basis_dimension m_stab_face_jump -= pi_c_f_k1_k @ local_reconstruction_operator[ c0_r:c1_r, :] m_stab_face_jump += pi_c_f_l_k @ ( pi_c_c_k1_l @ local_reconstruction_operator[c0_r:c1_r, :]) h_f = 1.0 / face.diameter local_stabilization_operator += h_f * m_stab_face_jump.T @ m_face_psi_k_psi_k_inv @ m_stab_face_jump return local_stabilization_operator
def get_local_gradient_operator( self, cell: Cell, faces: List[Face], cell_basis_l: Basis, cell_basis_k: Basis, cell_basis_k1: Basis, face_basis_k: Basis, unknown: Unknown, ) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ # -------------------------------------------------------------------------------------------------------------- # Getting the local problem size depending on the problem dimension and the field dimension # -------------------------------------------------------------------------------------------------------------- local_problem_size = self.get_local_problem_size( faces, cell_basis_l, face_basis_k, unknown) # -------------------------------------------------------------------------------------------------------------- # Initializing the local gradient operator matrix # -------------------------------------------------------------------------------------------------------------- local_gradient_operator = np.zeros( (len(unknown.indices) * cell_basis_k.basis_dimension, local_problem_size)) # -------------------------------------------------------------------------------------------------------------- m_cell_phi_k_phi_k = Integration.get_cell_mass_matrix_in_cell( cell, cell_basis_k, cell_basis_k) m_cell_phi_k_phi_k_inv = np.linalg.inv(m_cell_phi_k_phi_k) # -------------------------------------------------------------------------------------------------------------- derivative_directions = range(unknown.problem_dimension) directions = range(unknown.field_dimension) for j in derivative_directions: # ---------------------------------------------------------------------------------------------------------- # Compting matrices 1 # ---------------------------------------------------------------------------------------------------------- m_cell_phi_k_grad_phi_l = Integration.get_cell_advection_matrix_in_cell( cell, cell_basis_k, cell_basis_l, j) for f, face in enumerate(faces): passmat = Operator.get_face_passmat(cell, face) normal_vector_component = passmat[-1, j] # m_face_phi_l_psi_k = Integration.get_hybrid_mass_matrix_in_face( # cell, face, cell_basis_l, face_basis_k, passmat # ) m_face_phi_k_psi_k = Integration.get_hybrid_mass_matrix_in_face( cell, face, cell_basis_k, face_basis_k, passmat) m_face_phi_k_phi_l = Integration.get_cell_mass_matrix_in_face( cell, face, cell_basis_k, cell_basis_l) for i in directions: # -------------------------------------------------------------------------------------------------- # bkbjkj # -------------------------------------------------------------------------------------------------- line = self.get_line_from_indices(i, j, unknown) r0 = line * cell_basis_k.basis_dimension r1 = (line + 1) * cell_basis_k.basis_dimension # -------------------------------------------------------------------------------------------------- c0_T = i * cell_basis_l.basis_dimension c1_T = (i + 1) * cell_basis_l.basis_dimension # -------------------------------------------------------------------------------------------------- # Getting the indices corresponding to the face_index-th face for the field on the ith axis # -------------------------------------------------------------------------------------------------- c0_F = (unknown.field_dimension * cell_basis_l.basis_dimension + f * unknown.field_dimension * face_basis_k.basis_dimension + i * face_basis_k.basis_dimension) c1_F = (unknown.field_dimension * cell_basis_l.basis_dimension + f * unknown.field_dimension * face_basis_k.basis_dimension + (i + 1) * face_basis_k.basis_dimension) # -------------------------------------------------------------------------------------------------- # grad # -------------------------------------------------------------------------------------------------- # local_gradient_operator[r0:r1, c0_T:c1_T] += m_cell_phi_k_grad_phi_l local_gradient_operator[ r0:r1, c0_F: c1_F] += m_face_phi_k_psi_k * normal_vector_component local_gradient_operator[ r0:r1, c0_T: c1_T] -= m_face_phi_k_phi_l * normal_vector_component for i in directions: line = self.get_line_from_indices(i, j, unknown) r0 = line * cell_basis_k.basis_dimension r1 = (line + 1) * cell_basis_k.basis_dimension # ------------------------------------------------------------------------------------------------------ c0_T = i * cell_basis_l.basis_dimension c1_T = (i + 1) * cell_basis_l.basis_dimension local_gradient_operator[r0:r1, c0_T:c1_T] += m_cell_phi_k_grad_phi_l local_gradient_operator[ r0: r1, :] = m_cell_phi_k_phi_k_inv @ local_gradient_operator[ r0:r1, :] return local_gradient_operator
def __init__( self, cell_faces_connectivity_matrix: Mat, mcell: Mcell, mfaces: List[Mface], cell_basis_l: Basis, cell_basis_k: Basis, cell_basis_k1: Basis, unknown: Unknown, ): """ ================================================================================================================ Class : ================================================================================================================ The Mbox class ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Attributes : ================================================================================================================ - """ # ============================================================================================================== # GRADIENT OPERATOR / STABILIZATION OPERATOR # ============================================================================================================== self.mat_F_phi_k_phi_l_list = [] self.mat_F_phi_k_psi_k_list = [] for mface in mfaces: mat_F_phi_k_phi_l = Integration.get_cell_mass_matrix_in_face( mcell.cell, mface.face, cell_basis_k, cell_basis_l) self.mat_F_phi_k_phi_l_list.append(mat_F_phi_k_phi_l_list) # ---------------------------------------------------------------------------------------------------------- mat_F_phi_k_psi_k = Integration.get_hybrid_mass_matrix_in_face( mcell.cell, mface.face, cell_basis_k, face_basis_k, mface.face.reference_frame_transformation_matrix) self.mat_F_phi_k_psi_k_list.append(mat_F_phi_k_psi_k) # ============================================================================================================== # RECONSTRUCTION OPERATOR # ============================================================================================================== self.mat_F_grad_phi_k1_psi_k_list = [] self.mat_F_grad_phi_k1_phi_l_list = [] for mface in mfaces: mat_F_grad_phi_k1_psi_k_j_list = [] mat_F_grad_phi_k1_phi_l_j_list = [] for j in range(len(unknown.problem_dimension)): # ------------------------------------------------------------------------------------------------------ mat_F_grad_phi_k1_psi_k_j = Integration.get_hybrid_advection_matrix_in_face( mcell.cell, mface.face, cell_basis_k1, face_basis_k, mface.face.reference_frame_transformation_matrix, j, ) mat_F_grad_phi_k1_psi_k_j_list.append( mat_F_grad_phi_k1_psi_k_j) # ------------------------------------------------------------------------------------------------------ mat_F_phi_l_grad_phi_k1_j = Integration.get_cell_advection_matrix_in_face( mcell.cell, mface.face, cell_basis_l, cell_basis_k1, j) # ------------------------------------------------------------------------------------------------------ mat_F_grad_phi_k1_phi_l_j = mat_F_phi_l_grad_phi_k1_j.T mat_F_grad_phi_k1_phi_l_j_list.append( mat_F_grad_phi_k1_phi_l_j) # ---------------------------------------------------------------------------------------------------------- self.mat_F_grad_phi_k1_psi_k_list.append( mat_F_grad_phi_k1_psi_k_j_list) self.mat_F_grad_phi_k1_phi_l_list.append( mat_F_grad_phi_k1_phi_l_j_list) # ============================================================================================================== # STABILIZATION OPERATOR # ============================================================================================================== self.mat_F_psi_k_phi_k1_list = [] for mface in mfaces: mat_F_phi_k1_psi_k = Integration.get_hybrid_mass_matrix_in_face( mcell.cell, mface.face, cell_basis_k1, face_basis_k, mface.face.reference_frame_transformation_matrix) self.mat_F_psi_k_phi_k1_list.append(mat_F_phi_k1_psi_k)