def get_cell_stiffness_matrix_in_cell(cell: Cell, cell_basis_0: Basis, cell_basis_1: Basis, dx: int) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ v_c = cell.diameter x_c = cell.centroid # -------------------------------------------------------------------------------------------------------------- cell_stifness_matrix_in_cell = np.zeros((cell_basis_0.basis_dimension, cell_basis_1.basis_dimension)) # -------------------------------------------------------------------------------------------------------------- for x_Q_c, w_Q_c in zip(cell.quadrature_points, cell.quadrature_weights): # ---------------------------------------------------------------------------------------------------------- d_phi_vector_0 = cell_basis_0.get_d_phi_vector(x_Q_c, x_c, v_c, dx) number_of_components = d_phi_vector_0.shape[0] d_phi_vector_0 = np.resize(d_phi_vector_0, (1, number_of_components)) # ---------------------------------------------------------------------------------------------------------- d_phi_vector_1 = cell_basis_1.get_d_phi_vector(x_Q_c, x_c, v_c, dx) number_of_components = d_phi_vector_1.shape[0] d_phi_vector_1 = np.resize(d_phi_vector_1, (1, number_of_components)) # ---------------------------------------------------------------------------------------------------------- m = w_Q_c * d_phi_vector_0.T @ d_phi_vector_1 cell_stifness_matrix_in_cell += m return cell_stifness_matrix_in_cell
def get_cell_mass_matrix_in_face(cell: Cell, face: Face, cell_basis_0: Basis, cell_basis_1: Basis) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ x_c = cell.centroid v_c = cell.diameter # -------------------------------------------------------------------------------------------------------------- cell_mass_matrix_in_face = np.zeros((cell_basis_0.basis_dimension, cell_basis_1.basis_dimension)) # -------------------------------------------------------------------------------------------------------------- for x_Q_f, w_Q_f in zip(face.quadrature_points, face.quadrature_weights): # ---------------------------------------------------------------------------------------------------------- phi_vector_0 = cell_basis_0.get_phi_vector(x_Q_f, x_c, v_c) number_of_components = phi_vector_0.shape[0] phi_vector_0 = np.resize(phi_vector_0, (1, number_of_components)) # ---------------------------------------------------------------------------------------------------------- phi_vector_1 = cell_basis_1.get_phi_vector(x_Q_f, x_c, v_c) number_of_components = phi_vector_1.shape[0] phi_vector_1 = np.resize(phi_vector_1, (1, number_of_components)) # ---------------------------------------------------------------------------------------------------------- m = w_Q_f * phi_vector_0.T @ phi_vector_1 cell_mass_matrix_in_face += m return cell_mass_matrix_in_face
def get_hybrid_advection_matrix_in_face( cell: Cell, face: Face, cell_basis: Basis, face_basis: Basis, face_reference_frame_transformation_matrix: Mat, dx: int, ) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ v_f = face.diameter x_f = face.centroid v_c = cell.diameter x_c = cell.centroid # -------------------------------------------------------------------------------------------------------------- hybrid_advection_matrix_in_face = np.zeros((cell_basis.basis_dimension, face_basis.basis_dimension)) # -------------------------------------------------------------------------------------------------------------- x_f_in_face = Face.get_points_in_face_reference_frame(face.centroid, face_reference_frame_transformation_matrix) face_quadrature_points_in_face = Face.get_points_in_face_reference_frame( face.quadrature_points, face_reference_frame_transformation_matrix ) # -------------------------------------------------------------------------------------------------------------- for x_Q_f, x_Q_in_face, w_Q in zip( face.quadrature_points, face_quadrature_points_in_face, face.quadrature_weights ): # ---------------------------------------------------------------------------------------------------------- d_phi_vector = cell_basis.get_d_phi_vector(x_Q_f, x_c, v_c, dx) number_of_components = d_phi_vector.shape[0] d_phi_vector = np.resize(d_phi_vector, (1, number_of_components)) # ---------------------------------------------------------------------------------------------------------- psi_vector = face_basis.get_phi_vector(x_Q_in_face, x_f_in_face, v_f) number_of_components = psi_vector.shape[0] psi_vector = np.resize(psi_vector, (1, number_of_components)) # ---------------------------------------------------------------------------------------------------------- m = w_Q * d_phi_vector.T @ psi_vector hybrid_advection_matrix_in_face += m return hybrid_advection_matrix_in_face
def get_cell_integration_vector(cell: Cell, cell_basis: Basis) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ v_c = cell.diameter x_c = cell.centroid # -------------------------------------------------------------------------------------------------------------- cell_integration_vector = np.zeros((cell_basis.basis_dimension,)) # -------------------------------------------------------------------------------------------------------------- for x_Q_c, w_Q_c in zip(cell.quadrature_points, cell.quadrature_weights): # ---------------------------------------------------------------------------------------------------------- phi_vector = cell_basis.get_phi_vector(x_Q_c, x_c, v_c) v = w_Q_c * phi_vector cell_integration_vector += v return cell_integration_vector
def get_cell_load_vector_in_cell(cell: Cell, cell_basis: Basis, load: Callable) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ v_c = cell.diameter x_c = cell.centroid # -------------------------------------------------------------------------------------------------------------- cell_load_vector_in_cell = np.zeros((cell_basis.basis_dimension,)) # -------------------------------------------------------------------------------------------------------------- for x_Q_c, w_Q_c in zip(cell.quadrature_points, cell.quadrature_weights): # ---------------------------------------------------------------------------------------------------------- phi_vector = cell_basis.get_phi_vector(x_Q_c, x_c, v_c) v = w_Q_c * phi_vector * load(x_Q_c) cell_load_vector_in_cell += v return cell_load_vector_in_cell
def get_face_pressure_vector_in_face( face: Face, face_basis: Basis, face_reference_frame_transformation_matrix: Mat, pressure: Callable, ) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ v_f = face.diameter x_f = face.centroid # -------------------------------------------------------------------------------------------------------------- face_pressure_vector_in_face = np.zeros((face_basis.basis_dimension,)) # -------------------------------------------------------------------------------------------------------------- x_f_in_face = Face.get_points_in_face_reference_frame(face.centroid, face_reference_frame_transformation_matrix) face_quadrature_points_in_face = Face.get_points_in_face_reference_frame( face.quadrature_points, face_reference_frame_transformation_matrix ) for x_Q_f_in_face, w_Q_f in zip(face_quadrature_points_in_face, face.quadrature_weights): # ---------------------------------------------------------------------------------------------------------- psi_vector = face_basis.get_phi_vector(x_Q_f_in_face, x_f_in_face, v_f) v = w_Q_f * psi_vector * pressure(x_Q_f_in_face) face_pressure_vector_in_face += v return face_pressure_vector_in_face
def get_face_mass_matrix_in_face( face: Face, face_basis_0: Basis, face_basis_1: Basis, face_reference_frame_transformation_matrix: Mat ) -> Mat: """ ================================================================================================================ Method : ================================================================================================================ ================================================================================================================ Parameters : ================================================================================================================ - ================================================================================================================ Returns : ================================================================================================================ - """ v_f = face.diameter x_f = face.centroid # -------------------------------------------------------------------------------------------------------------- face_mass_matrix_in_face = np.zeros((face_basis_0.basis_dimension, face_basis_1.basis_dimension)) # -------------------------------------------------------------------------------------------------------------- x_f_in_face = Face.get_points_in_face_reference_frame(face.centroid, face_reference_frame_transformation_matrix) face_quadrature_points_in_face = Face.get_points_in_face_reference_frame( face.quadrature_points, face_reference_frame_transformation_matrix ) for x_Q_f_in_face, w_Q_f in zip(face_quadrature_points_in_face, face.quadrature_weights): # ---------------------------------------------------------------------------------------------------------- psi_vector_0 = face_basis_0.get_phi_vector(x_Q_f_in_face, x_f_in_face, v_f) number_of_components = psi_vector_0.shape[0] psi_vector_0 = np.resize(psi_vector_0, (1, number_of_components)) # ---------------------------------------------------------------------------------------------------------- psi_vector_1 = face_basis_1.get_phi_vector(x_Q_f_in_face, x_f_in_face, v_f) number_of_components = psi_vector_1.shape[0] psi_vector_1 = np.resize(psi_vector_1, (1, number_of_components)) # ---------------------------------------------------------------------------------------------------------- m = w_Q_f * psi_vector_0.T @ psi_vector_1 face_mass_matrix_in_face += m return face_mass_matrix_in_face
def solve( vertices: Mat, faces: List[Face], cells: List[Cell], operators: List[Operator], cells_faces_connectivity_matrix: Mat, cells_vertices_connectivity_matrix: Mat, faces_vertices_connectivity_matrix: Mat, nsets: dict, # flags: List[str], nsets_faces: dict, cell_basis_l: Basis, cell_basis_k: Basis, face_basis_k: Basis, unknown: Unknown, tangent_matrices: List[Mat], stabilization_parameter: float, boundary_conditions: dict, load: List[Callable], ): """ ==================================================================================================================== Description : ==================================================================================================================== ==================================================================================================================== Parameters : ==================================================================================================================== ==================================================================================================================== Exemple : ==================================================================================================================== """ # ------------------------------------------------------------------------------------------------------------------ # Global matrix # ------------------------------------------------------------------------------------------------------------------ number_of_faces = len(faces_vertices_connectivity_matrix) number_of_cells = len(cells_vertices_connectivity_matrix) total_system_size = number_of_faces * face_basis_k.basis_dimension * unknown.field_dimension global_matrix = np.zeros((total_system_size, total_system_size)) global_vector = np.zeros((total_system_size, )) stored_matrices = [] # ------------------------------------------------------------------------------------------------------------------ # Global matrix # ------------------------------------------------------------------------------------------------------------------ cells_indices = range(len(cells)) for cell_index in cells_indices: local_cell = cells[cell_index] local_faces = [ faces[i] for i in cells_faces_connectivity_matrix[cell_index] ] # -------------------------------------------------------------------------------------------------------------- # External forces # -------------------------------------------------------------------------------------------------------------- number_of_local_faces = len(local_faces) a = unknown.field_dimension * ( cell_basis_l.basis_dimension + number_of_local_faces * face_basis_k.basis_dimension) local_external_forces = np.zeros((a, )) load_vector = Load(local_cell, cell_basis_l, unknown, load).load_vector l0 = 0 l1 = unknown.field_dimension * cell_basis_l.basis_dimension local_external_forces[l0:l1] += load_vector connectivity = cells_faces_connectivity_matrix[cell_index] local_faces_indices = cells_faces_connectivity_matrix[cell_index] for local_face_index, global_face_index in enumerate( local_faces_indices): face = faces[global_face_index] face_reference_frame_transformation_matrix = Operator.get_face_passmat( local_cell, face) # for boundary_name, nset in zip(nsets, nsets.values()): for boundary_name, nset in zip(nsets_faces, nsets_faces.values()): if connectivity[local_face_index] in nset: pressure = boundary_conditions[boundary_name][1] pressure_vector = Pressure( face, face_basis_k, face_reference_frame_transformation_matrix, unknown, pressure).pressure_vector else: pressure_vector = Pressure( face, face_basis_k, face_reference_frame_transformation_matrix, unknown).pressure_vector l0 = local_face_index * unknown.field_dimension * face_basis_k.basis_dimension l1 = (local_face_index + 1) * unknown.field_dimension * face_basis_k.basis_dimension local_external_forces[l0:l1] += pressure_vector # -------------------------------------------------------------------------------------------------------------- # Stffness matrix # -------------------------------------------------------------------------------------------------------------- tangent_matrix = tangent_matrices[cell_index] tangent_matrix_size = tangent_matrix.shape[0] total_size = tangent_matrix_size * cell_basis_k.basis_dimension local_mass_matrix = np.zeros((total_size, total_size)) m_phi_phi_cell = Integration.get_cell_mass_matrix_in_cell( local_cell, cell_basis_k, cell_basis_k) for i in range(tangent_matrix.shape[0]): for j in range(tangent_matrix.shape[1]): m = tangent_matrix[i, j] * m_phi_phi_cell # ------------------------------------------------------------------------------------------------------ l0 = i * cell_basis_k.basis_dimension l1 = (i + 1) * cell_basis_k.basis_dimension c0 = j * cell_basis_k.basis_dimension c1 = (j + 1) * cell_basis_k.basis_dimension # ------------------------------------------------------------------------------------------------------ local_mass_matrix[l0:l1, c0:c1] += m local_gradient_operator = operators[cell_index].local_gradient_operator # print(local_gradient_operator.shape) local_stiffness_form = local_gradient_operator.T @ local_mass_matrix @ local_gradient_operator # -------------------------------------------------------------------------------------------------------------- # Stabilization matrix # -------------------------------------------------------------------------------------------------------------- local_stabilization_operator = stabilization_parameter * operators[ cell_index].local_stabilization_operator # -------------------------------------------------------------------------------------------------------------- # Local matrix # -------------------------------------------------------------------------------------------------------------- local_matrix = local_stiffness_form + local_stabilization_operator # -------------------------------------------------------------------------------------------------------------- # Static condensation # -------------------------------------------------------------------------------------------------------------- ( m_cell_cell_inv, m_cell_faces, m_faces_cell, m_faces_faces, v_cell, v_faces, ) = Condensation.get_system_decomposition(local_matrix, local_external_forces, unknown, cell_basis_l) # -------------------------------------------------------------------------------------------------------------- # Static condensation # -------------------------------------------------------------------------------------------------------------- m_cond, v_cond = Condensation.get_condensated_system( m_cell_cell_inv, m_cell_faces, m_faces_cell, m_faces_faces, v_cell, v_faces, ) v_cell, m_cell_faces, m_cell_cell_inv stored_matrices.append((v_cell, m_cell_faces, m_cell_cell_inv)) # -------------------------------------------------------------------------------------------------------------- # Assembly # -------------------------------------------------------------------------------------------------------------- cell_faces_connectivity_matrix = cells_faces_connectivity_matrix[ cell_index] for local_index_col, global_index_col in enumerate( cell_faces_connectivity_matrix): g0c = global_index_col * face_basis_k.basis_dimension * unknown.field_dimension g1c = (global_index_col + 1) * face_basis_k.basis_dimension * unknown.field_dimension l0c = local_index_col * face_basis_k.basis_dimension * unknown.field_dimension l1c = (local_index_col + 1) * face_basis_k.basis_dimension * unknown.field_dimension global_vector[g0c:g1c] += v_cond[l0c:l1c] for local_index_row, global_index_row in enumerate( cell_faces_connectivity_matrix): g0r = global_index_row * face_basis_k.basis_dimension * unknown.field_dimension g1r = ( global_index_row + 1) * face_basis_k.basis_dimension * unknown.field_dimension l0r = local_index_row * face_basis_k.basis_dimension * unknown.field_dimension l1r = ( local_index_row + 1) * face_basis_k.basis_dimension * unknown.field_dimension global_matrix[g0r:g1r, g0c:g1c] += m_cond[l0r:l1r, l0c:l1c] # ------------------------------------------------------------------------------------------------------------------ # Displacement enforcement through Lagrange multiplier # ------------------------------------------------------------------------------------------------------------------ number_of_constrained_faces = 0 # for boundary_name, nset in zip(nsets, nsets.values()): for boundary_name, nset in zip(nsets_faces, nsets_faces.values()): # print(boundary_name, nset) displacement = boundary_conditions[boundary_name][0] for displacement_component in displacement: if not displacement_component is None: number_of_constrained_faces += len(nset) lagrange_multiplyer_matrix = np.zeros(( number_of_constrained_faces * face_basis_k.basis_dimension, number_of_faces * unknown.field_dimension * face_basis_k.basis_dimension, )) h_vector = np.zeros( (number_of_constrained_faces * face_basis_k.basis_dimension, )) iter_constrained_face = 0 # for boundary_name, nset in zip(nsets, nsets.values()): for boundary_name, nset in zip(nsets_faces, nsets_faces.values()): for face_global_index in nset: face = faces[face_global_index] face_reference_frame_transformation_matrix = face.reference_frame_transformation_matrix # ---------------------------------------------------------------------------------------------------------- m_psi_psi_face = Integration.get_face_mass_matrix_in_face( face, face_basis_k, face_basis_k, face_reference_frame_transformation_matrix) m_psi_psi_face_inv = np.linalg.inv(m_psi_psi_face) # ---------------------------------------------------------------------------------------------------------- displacement = boundary_conditions[boundary_name][0] for direction, displacement_component in enumerate(displacement): if not displacement_component is None: displacement_vector = Displacement( face, face_basis_k, face_reference_frame_transformation_matrix, displacement_component).displacement_vector # if False: # print("hello") # displacement_vector = np.zeros((face_basis.basis_dimension,)) # if displacement_component(0) != 0: # displacement_vector[0] = 1.0 # print(displacement_vector) # -------------------------------------------------------------------------------------------------- displacement_vector = m_psi_psi_face_inv @ displacement_vector # -------------------------------------------------------------------------------------------------- l0 = iter_constrained_face * face_basis_k.basis_dimension l1 = (iter_constrained_face + 1) * face_basis_k.basis_dimension c0 = (face_global_index * unknown.field_dimension * face_basis_k.basis_dimension + direction * face_basis_k.basis_dimension) c1 = (face_global_index * unknown.field_dimension * face_basis_k.basis_dimension ) + (direction + 1) * face_basis_k.basis_dimension # -------------------------------------------------------------------------------------------------- lagrange_multiplyer_matrix[l0:l1, c0:c1] += np.eye( face_basis_k.basis_dimension) # -------------------------------------------------------------------------------------------------- h_vector[l0:l1] += displacement_vector iter_constrained_face += 1 # print("h_vector : \n{}".format(h_vector)) # print("lagrange_multiplyer_matrix : \n{}".format(lagrange_multiplyer_matrix)) # ------------------------------------------------------------------------------------------------------------------ double_lagrange = False # ------------------------------------------------------------------------------------------------------------------ # If a single Lagrange multiplyier is used to enforce Dirichlet boundary conditions # ------------------------------------------------------------------------------------------------------------------ if not double_lagrange: global_vector_2 = np.zeros( (total_system_size + number_of_constrained_faces * face_basis_k.basis_dimension, )) # -------------------------------------------------------------------------------------------------------------- global_vector_2[:total_system_size] += global_vector global_vector_2[total_system_size:] += h_vector # -------------------------------------------------------------------------------------------------------------- global_matrix_2 = np.zeros(( total_system_size + number_of_constrained_faces * face_basis_k.basis_dimension, total_system_size + number_of_constrained_faces * face_basis_k.basis_dimension, )) # -------------------------------------------------------------------------------------------------------------- global_matrix_2[:total_system_size, : total_system_size] += global_matrix global_matrix_2[:total_system_size, total_system_size:] += lagrange_multiplyer_matrix.T global_matrix_2[total_system_size:, : total_system_size] += lagrange_multiplyer_matrix # ------------------------------------------------------------------------------------------------------------------ # If double Lagrange multiplyiers are used to enforce Dirichlet boundary conditions # ------------------------------------------------------------------------------------------------------------------ else: global_vector_2 = np.zeros( (total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension), )) # -------------------------------------------------------------------------------------------------------------- l0 = 0 l1 = total_system_size global_vector_2[l0:l1] += global_vector # -------------------------------------------------------------------------------------------------------------- l0 = total_system_size l1 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) global_vector_2[l0:l1] += h_vector # -------------------------------------------------------------------------------------------------------------- l0 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) l1 = total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension) global_vector_2[l0:l1] += h_vector # -------------------------------------------------------------------------------------------------------------- global_matrix_2 = np.zeros(( total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension), total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension), )) # -------------------------------------------------------------------------------------------------------------- l0 = 0 l1 = total_system_size c0 = 0 c1 = total_system_size global_matrix_2[l0:l1, c0:c1] += global_matrix # -------------------------------------------------------------------------------------------------------------- l0 = 0 l1 = total_system_size c0 = total_system_size c1 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) global_matrix_2[l0:l1, c0:c1] += lagrange_multiplyer_matrix.T # -------------------------------------------------------------------------------------------------------------- l0 = 0 l1 = total_system_size c0 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) c1 = total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension) global_matrix_2[l0:l1, c0:c1] += lagrange_multiplyer_matrix.T # -------------------------------------------------------------------------------------------------------------- l0 = total_system_size l1 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) c0 = 0 c1 = total_system_size global_matrix_2[l0:l1, c0:c1] += lagrange_multiplyer_matrix # -------------------------------------------------------------------------------------------------------------- l0 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) l1 = total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension) c0 = 0 c1 = total_system_size global_matrix_2[l0:l1, c0:c1] += lagrange_multiplyer_matrix # -------------------------------------------------------------------------------------------------------------- id_lag = np.eye(number_of_constrained_faces * face_basis_k.basis_dimension) # -------------------------------------------------------------------------------------------------------------- l0 = total_system_size l1 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) c0 = total_system_size c1 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) global_matrix_2[l0:l1, c0:c1] += id_lag # -------------------------------------------------------------------------------------------------------------- l0 = total_system_size l1 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) c0 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) c1 = total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension) global_matrix_2[l0:l1, c0:c1] -= id_lag # -------------------------------------------------------------------------------------------------------------- l0 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) l1 = total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension) c0 = total_system_size c1 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) global_matrix_2[l0:l1, c0:c1] -= id_lag # -------------------------------------------------------------------------------------------------------------- l0 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) l1 = total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension) c0 = total_system_size + (number_of_constrained_faces * face_basis_k.basis_dimension) c1 = total_system_size + 2 * (number_of_constrained_faces * face_basis_k.basis_dimension) global_matrix_2[l0:l1, c0:c1] += id_lag # print("global_matrix_2 : \n{}".format(global_matrix_2)) # print("global_vector_2 : \n{}".format(global_vector_2)) # ------------------------------------------------------------------------------------------------------------------ # Solving the global system for faces unknowns # ------------------------------------------------------------------------------------------------------------------ # print("global_matrix : \n{}".format(global_matrix_2)) global_solution = np.linalg.solve(global_matrix_2, global_vector_2) # print("global_solution : \n{}".format(global_solution)) # ------------------------------------------------------------------------------------------------------------------ # Getting the number of vertices # ------------------------------------------------------------------------------------------------------------------ number_of_quadrature_points = 0 for cell in cells: number_of_quadrature_points_in_cell = cell.quadrature_points.shape[0] number_of_quadrature_points += number_of_quadrature_points_in_cell number_of_vertices = vertices.shape[0] # ------------------------------------------------------------------------------------------------------------------ quadrature_points = np.zeros( (number_of_quadrature_points, unknown.problem_dimension)) quadrature_weights = np.zeros((number_of_quadrature_points, )) unknowns_at_vertices = [ np.zeros((number_of_vertices, )) for i in range(unknown.field_dimension) ] f_unknowns_at_vertices = [ np.zeros((number_of_vertices, )) for i in range(unknown.field_dimension) ] unknowns_at_quadrature_points = [ np.zeros((number_of_quadrature_points, )) for i in range(unknown.field_dimension) ] vertices_weights = np.zeros((number_of_vertices, )) f_vertices_weights = np.zeros((number_of_vertices, )) # ------------------------------------------------------------------------------------------------------------------ # Desassembly # ------------------------------------------------------------------------------------------------------------------ quadrature_point_count = 0 # ================================================================================================================== # ================================================================================================================== faces_indices = range(number_of_faces) for face_index in faces_indices: face_vertices_connectivity_matrix = faces_vertices_connectivity_matrix[ face_index] face_vertices = vertices[face_vertices_connectivity_matrix] face = faces[face_index] l0 = face_index * unknown.field_dimension * face_basis_k.basis_dimension l1 = (face_index + 1) * unknown.field_dimension * face_basis_k.basis_dimension x_face = global_solution[l0:l1] for i, vertex in enumerate(face_vertices): vertex_in_face = Face.get_points_in_face_reference_frame( vertex, face.reference_frame_transformation_matrix) centroid_in_face = Face.get_points_in_face_reference_frame( face.centroid, face.reference_frame_transformation_matrix) v = face_basis_k.get_phi_vector(vertex_in_face, centroid_in_face, face.diameter) for direction in range(unknown.field_dimension): l0 = direction * face_basis_k.basis_dimension l1 = (direction + 1) * face_basis_k.basis_dimension vertex_value_vector = v * x_face[l0:l1] global_index = face_vertices_connectivity_matrix[i] l0 = global_index l1 = global_index + 1 f_unknowns_at_vertices[direction][l0:l1] += np.sum( vertex_value_vector) f_vertices_weights[l0:l1] += 1.0 # ================================================================================================================== # ================================================================================================================== x_cell_list, x_faces_list = [], [] for cell_index in cells_indices: # -------------------------------------------------------------------------------------------------------------- # Getting faces unknowns # -------------------------------------------------------------------------------------------------------------- local_cell = cells[cell_index] cell_faces_connectivity_matrix = cells_faces_connectivity_matrix[ cell_index] local_faces = [faces[i] for i in cell_faces_connectivity_matrix] faces_unknown_dimension = len( local_faces ) * face_basis_k.basis_dimension * unknown.field_dimension x_faces = np.zeros((faces_unknown_dimension, )) for local_index_col, global_index_col in enumerate( cell_faces_connectivity_matrix): g0c = global_index_col * face_basis_k.basis_dimension * unknown.field_dimension g1c = (global_index_col + 1) * face_basis_k.basis_dimension * unknown.field_dimension l0c = local_index_col * face_basis_k.basis_dimension * unknown.field_dimension l1c = (local_index_col + 1) * face_basis_k.basis_dimension * unknown.field_dimension x_faces[l0c:l1c] += global_solution[g0c:g1c] # -------------------------------------------------------------------------------------------------------------- # Decondensation : getting cell unknowns # -------------------------------------------------------------------------------------------------------------- (v_cell, m_cell_faces, m_cell_cell_inv) = stored_matrices[cell_index] x_cell = Condensation.get_cell_unknown(m_cell_cell_inv, m_cell_faces, v_cell, x_faces) x_cell_list.append(x_cell) x_faces_list.append(x_faces) x_element = np.zeros((len(x_cell) + len(x_faces), )) p1 = cell_basis_l.basis_dimension * unknown.field_dimension x_element[:p1] += x_cell x_element[p1:] += x_faces # operators[cell_index] # -------------------------------------------------------------------------------------------------------------- cell_vertices_connectivity_matrix = cells_vertices_connectivity_matrix[ cell_index] local_vertices = vertices[cell_vertices_connectivity_matrix] # -------------------------------------------------------------------------------------------------------------- for i, vertex in enumerate(local_vertices): v = cell_basis_l.get_phi_vector(vertex, local_cell.centroid, local_cell.diameter) for direction in range(unknown.field_dimension): l0 = direction * cell_basis_l.basis_dimension l1 = (direction + 1) * cell_basis_l.basis_dimension vertex_value_vector = v * x_cell[l0:l1] global_index = cell_vertices_connectivity_matrix[i] l0 = global_index l1 = global_index + 1 unknowns_at_vertices[direction][l0:l1] += np.sum( vertex_value_vector) vertices_weights[l0:l1] += 1.0 # -------------------------------------------------------------------------------------------------------------- for i, quadrature_point in enumerate(local_cell.quadrature_points): v = cell_basis_l.get_phi_vector(quadrature_point, local_cell.centroid, local_cell.diameter) for direction in range(unknown.field_dimension): l0 = direction * cell_basis_l.basis_dimension l1 = (direction + 1) * cell_basis_l.basis_dimension vertex_value_vector = v * x_cell[l0:l1] l0 = quadrature_point_count l1 = quadrature_point_count + 1 unknowns_at_quadrature_points[direction][l0:l1] += np.sum( vertex_value_vector) quadrature_points[quadrature_point_count] += quadrature_point quadrature_weights[ quadrature_point_count] += local_cell.quadrature_weights[i] quadrature_point_count += 1 # ------------------------------------------------------------------------------------------------------------------ # Global matrix # ------------------------------------------------------------------------------------------------------------------ for direction in range(unknown.field_dimension): unknowns_at_vertices[ direction] = unknowns_at_vertices[direction] / vertices_weights f_unknowns_at_vertices[ direction] = f_unknowns_at_vertices[direction] / f_vertices_weights return ( (vertices, unknowns_at_vertices), (quadrature_points, unknowns_at_quadrature_points, quadrature_weights), (vertices, f_unknowns_at_vertices), (x_cell_list, x_faces_list), # unknowns_at_faces )