コード例 #1
0
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
    )
コード例 #2
0
 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
コード例 #3
0
 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
コード例 #4
0
    def get_local_reconstruction_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_reconstruction_operator = np.zeros(
            ((unknown.field_dimension) * cell_basis_k1.basis_dimension,
             local_problem_size))
        # --------------------------------------------------------------------------------------------------------------
        derivative_directions = range(unknown.problem_dimension)
        directions = range(unknown.field_dimension)
        m_cell_grad_phi_k1_grad_phi_k1_sum = np.zeros(
            (cell_basis_k1.basis_dimension, cell_basis_k1.basis_dimension))
        m_cell_grad_phi_k1_grad_phi_l_sum = np.zeros(
            (cell_basis_k1.basis_dimension, cell_basis_l.basis_dimension))
        for j in derivative_directions:
            m_cell_grad_phi_k1_grad_phi_k1 = Integration.get_cell_stiffness_matrix_in_cell(
                cell, cell_basis_k1, cell_basis_k1, j)
            m_cell_grad_phi_k1_grad_phi_k1_sum += m_cell_grad_phi_k1_grad_phi_k1
            m_cell_grad_phi_k1_grad_phi_l = Integration.get_cell_stiffness_matrix_in_cell(
                cell, cell_basis_k1, cell_basis_l, j)
            m_cell_grad_phi_k1_grad_phi_l_sum += m_cell_grad_phi_k1_grad_phi_l
        for f, face in enumerate(faces):
            passmat = Operator.get_face_passmat(cell, face)
            normal_vector_component = passmat[-1, j]
            m_face_grad_phi_k1_phi_l_sum = np.zeros(
                (cell_basis_k1.basis_dimension, cell_basis_l.basis_dimension))
            m_face_grad_phi_k1_psi_k_sum = np.zeros(
                (cell_basis_k1.basis_dimension, face_basis_k.basis_dimension))
            for j in derivative_directions:
                m_face_grad_phi_k1_psi_k = Integration.get_hybrid_advection_matrix_in_face(
                    cell, face, cell_basis_k1, face_basis_k, passmat, j)
                m_face_grad_phi_k1_psi_k_sum += m_face_grad_phi_k1_psi_k
                m_face_phi_l_grad_phi_k1 = Integration.get_cell_advection_matrix_in_face(
                    cell, face, cell_basis_l, cell_basis_k1, j)
                m_face_grad_phi_k1_phi_l = m_face_phi_l_grad_phi_k1.T
                m_face_grad_phi_k1_phi_l_sum += m_face_grad_phi_k1_phi_l
            for i in directions:
                # --------------------------------------------------------------------------------------------------
                # bkbjkj
                # --------------------------------------------------------------------------------------------------
                r0 = i * cell_basis_k1.basis_dimension
                r1 = (i + 1) * cell_basis_k1.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)
                c0_T = i * cell_basis_l.basis_dimension
                c1_T = (i + 1) * cell_basis_l.basis_dimension
                # --------------------------------------------------------------------------------------------------
                # rec
                # --------------------------------------------------------------------------------------------------
                local_reconstruction_operator[r0:r1, c0_F:c1_F] += (
                    m_face_grad_phi_k1_psi_k_sum * normal_vector_component)
                local_reconstruction_operator[r0:r1, c0_T:c1_T] -= (
                    m_face_grad_phi_k1_phi_l_sum * normal_vector_component)
        for i in directions:
            r0 = i * cell_basis_k1.basis_dimension
            r1 = (i + 1) * cell_basis_k1.basis_dimension
            m_cell_grad_phi_k1_grad_phi_k1_sum_inv = np.linalg.inv(
                m_cell_grad_phi_k1_grad_phi_k1_sum[1:, 1:])
            local_reconstruction_operator[r0 + 1:r1, :] = (
                m_cell_grad_phi_k1_grad_phi_k1_sum_inv
                @ local_reconstruction_operator[r0 + 1:r1, :])
            # ------------------------------------------------------------------------------------------------------
            cell_integration_vector_k1 = Integration.get_cell_integration_vector(
                cell, cell_basis_k1)
            cell_integration_vector_l = Integration.get_cell_integration_vector(
                cell, cell_basis_l)
            # ------------------------------------------------------------------------------------------------------
            m_mat = np.zeros(
                (cell_basis_l.basis_dimension, local_problem_size))
            c0_m = i * cell_basis_l.basis_dimension
            c1_m = (i + 1) * cell_basis_l.basis_dimension
            m_mat[:, c0_m:c1_m] += np.eye(cell_basis_l.basis_dimension)
            # ------------------------------------------------------------------------------------------------------
            a = (cell_integration_vector_l @ m_mat -
                 cell_integration_vector_k1[1:]
                 @ local_reconstruction_operator[r0 + 1:r1, :])
            a = (1.0 / cell_integration_vector_k1[0]) * a
            local_reconstruction_operator[r0:r0 + 1, :] = a
        # for i in directions:
        #     r0 = i * cell_basis_k1.basis_dimension
        #     r1 = (i + 1) * cell_basis_k1.basis_dimension
        #     c0_T = i * cell_basis_l.basis_dimension
        #     c1_T = (i + 1) * cell_basis_l.basis_dimension
        #     #
        #     local_reconstruction_operator[r0:r1, c0_T:c1_T] += m_cell_grad_phi_k1_grad_phi_l_sum
        #     local_reconstruction_operator[r0:r1, :] = local_reconstruction_operator[r0:r1, :]

        # for j in derivative_directions:
        #     # ------------------------------------------------------------------------------------------------------
        #     # Compting matrices 1
        #     # ------------------------------------------------------------------------------------------------------
        #     m_cell_grad_phi_k1_grad_phi_k1 = Integration.get_cell_stiffness_matrix_in_cell(
        #         cell, cell_basis_k1, cell_basis_k1, j
        #     )
        #     m_cell_grad_phi_k1_grad_phi_k1_sum += m_cell_grad_phi_k1_grad_phi_k1
        #     m_cell_grad_phi_k1_grad_phi_l = Integration.get_cell_stiffness_matrix_in_cell(
        #         cell, cell_basis_k1, 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_grad_phi_k1_psi_k
        #         m_face_grad_phi_k1_psi_k = Integration.get_hybrid_advection_matrix_in_face(
        #             cell, face, cell_basis_k1, face_basis_k, passmat, j
        #         )
        #         # m_face_grad_phi_k1_phi_l = Integration.get_cell_advection_matrix_in_face(
        #         #     cell, face, cell_basis_k1, cell_basis_l, j
        #         # )
        #         m_face_phi_l_grad_phi_k1 = Integration.get_cell_advection_matrix_in_face(
        #             cell, face, cell_basis_l, cell_basis_k1, j
        #         )
        #         m_face_grad_phi_k1_phi_l = m_face_phi_l_grad_phi_k1.T
        #         for i in directions:
        #             # --------------------------------------------------------------------------------------------------
        #             # bkbjkj
        #             # --------------------------------------------------------------------------------------------------
        #             r0 = i * cell_basis_k1.basis_dimension
        #             r1 = (i + 1) * cell_basis_k1.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
        #             )
        #             # --------------------------------------------------------------------------------------------------
        #             # rec
        #             # --------------------------------------------------------------------------------------------------
        #             local_reconstruction_operator[r0:r1, c0_F:c1_F] += (
        #                 m_face_grad_phi_k1_psi_k * normal_vector_component
        #             )
        #             local_reconstruction_operator[r0:r1, c0_T:c1_T] -= (
        #                 m_face_grad_phi_k1_phi_l * normal_vector_component
        #             )
        #     for i in directions:
        #         r0 = i * cell_basis_k1.basis_dimension
        #         r1 = (i + 1) * cell_basis_k1.basis_dimension
        #         # ------------------------------------------------------------------------------------------------------
        #         c0_T = i * cell_basis_l.basis_dimension
        #         c1_T = (i + 1) * cell_basis_l.basis_dimension
        #         local_reconstruction_operator[r0:r1, c0_T:c1_T] += m_cell_grad_phi_k1_grad_phi_l
        # # --------------------------------------------------------------------------------------------------------------
        # for i in directions:
        #     # a_sum = np.zeros((local_problem_size,))
        #     # for i_sum in directions:
        #     r0 = i * cell_basis_k1.basis_dimension
        #     r1 = (i + 1) * cell_basis_k1.basis_dimension
        #     # print("grad_matrx : \n{}".format(m_cell_grad_phi_k1_grad_phi_k1_sum[1:, 1:]))
        #     m_cell_grad_phi_k1_grad_phi_k1_sum_inv = np.linalg.inv(m_cell_grad_phi_k1_grad_phi_k1_sum[1:, 1:])
        #     local_reconstruction_operator[r0 + 1 : r1, :] = (
        #         m_cell_grad_phi_k1_grad_phi_k1_sum_inv @ local_reconstruction_operator[r0 + 1 : r1, :]
        #     )
        #     # ------------------------------------------------------------------------------------------------------
        #     cell_integration_vector_k1 = Integration.get_cell_integration_vector(cell, cell_basis_k1)
        #     cell_integration_vector_l = Integration.get_cell_integration_vector(cell, cell_basis_l)
        #     # ------------------------------------------------------------------------------------------------------
        #     m_mat = np.zeros((cell_basis_l.basis_dimension, local_problem_size))
        #     c0_m = i * cell_basis_l.basis_dimension
        #     c1_m = (i + 1) * cell_basis_l.basis_dimension
        #     m_mat[:, c0_m:c1_m] += np.eye(cell_basis_l.basis_dimension)
        #     # ------------------------------------------------------------------------------------------------------
        #     a = (
        #         cell_integration_vector_l @ m_mat
        #         - cell_integration_vector_k1[1:] @ local_reconstruction_operator[r0 + 1 : r1, :]
        #     )
        #     a = (1.0 / cell_integration_vector_k1[0]) * a
        #     local_reconstruction_operator[r0 : r0 + 1, :] = a
        return local_reconstruction_operator