Exemplo n.º 1
0
Arquivo: fem.py Projeto: basic-ph/feat
def sp_base_analysis(mesh, element_type):
    # MESH
    # mesh = meshio.read(mesh_path)
    elements = mesh.cells_dict[element_type]
    nodal_coord = mesh.points[:, :2]
    num_elements = elements.shape[0]
    num_nodes = nodal_coord.shape[0]
    material_map = mesh.cell_data_dict["gmsh:physical"][
        element_type] - 1  # element-material map
    logger.debug("mesh info: %d elements, %d nodes", num_elements, num_nodes)
    # DATA
    integration_points = 1  # hard-coded but could be removed
    load_condition = "plane strain"  # TODO also this could be removed 'cause we need only plane strain case
    thickness = 1  # TODO make this a passed argument?
    # MATERIAL
    matrix = base.Material("matrix", 10, 0.3, load_condition)
    fiber = base.Material("fiber", 100, 0.3, load_condition)

    # BOUNDARY CONDITIONS INSTANCES
    left_side = bc.DirichletBC("left side", mesh, [0], 0.0)
    bl_corner = bc.DirichletBC("bottom left corner", mesh, [1], 0.0)
    right_side = bc.DirichletBC("right side", mesh, [0], 1.0)

    # ASSEMBLY
    E_material = base.compute_E_material(num_elements, material_map,
                                         mesh.field_data, matrix, fiber)
    K = sparse.csc_matrix((2 * num_nodes, 2 * num_nodes))
    R = np.zeros(num_nodes * 2)
    K = base.sp_assembly(K, num_elements, num_nodes, elements, nodal_coord,
                         material_map, E_material, thickness, element_type)

    # save constrained dof rows of K
    # dirichlet dof are built only for boundaries with related reactions
    dirichlet_dof, dirichlet_values = bc.build_dirichlet_data(
        left_side, bl_corner)
    K = K.tocsr()
    K_rows = K[dirichlet_dof, :]
    K = K.tocsc()

    # BOUNDARY CONDITIONS APPLICATION
    K, R = bc.sp_apply_dirichlet(num_nodes, K, R, left_side, bl_corner,
                                 right_side)
    # SOLVER
    D = linalg.spsolve(K, R)
    reactions = K_rows.dot(D)
    modulus = base.compute_modulus(nodal_coord, right_side, reactions,
                                   thickness)
    logger.debug("E2 = %f", modulus)

    return modulus
Exemplo n.º 2
0
def test_stiffness_matrix():
    mesh_path = "tests/data/msh/test.msh"

    element_type = "triangle"
    load_condition = "plane stress"  # "plane stress" or "plane strain"
    thickness = 0.5
    steel = base.Material("steel", 3e7, 0.25, load_condition)

    mesh = meshio.read(mesh_path)
    elements = mesh.cells_dict[element_type]
    nodal_coord = mesh.points[:, :2]
    num_elements = elements.shape[0]
    num_nodes = nodal_coord.shape[0]
    material_map = mesh.cell_data_dict["gmsh:physical"][
        element_type] - 1  # element-material map
    E_material = base.compute_E_material(num_elements, material_map,
                                         mesh.field_data, steel)

    k_0 = base.stiffness_matrix(0, elements, nodal_coord, material_map,
                                E_material, thickness, element_type)
    k_1 = base.stiffness_matrix(1, elements, nodal_coord, material_map,
                                E_material, thickness, element_type)

    k_0_true = np.array([
        (5333333.33333333, 0.0, -5333333.33333333, 2000000., 0., -2000000.),
        (0., 2000000., 3000000., -2000000., -3000000., 0.),
        (-5333333.33333333, 3000000., 9833333.33333333, -5000000., -4500000.,
         2000000.),
        (2000000., -2000000., -5000000., 14000000., 3000000., -12000000.),
        (0., -3000000., -4500000., 3000000., 4500000., 0.),
        (-2000000., 0., 2000000., -12000000., 0., 12000000.),
    ])
    k_1_true = np.array([
        (4500000., 0., 0., -3000000., -4500000., 3000000.),
        (0., 12000000., -2000000., 0., 2000000., -12000000.),
        (0., -2000000., 5333333.33333333, 0., -5333333.33333333, 2000000.),
        (-3000000., 0., 0., 2000000., 3000000., -2000000.),
        (-4500000., 2000000., -5333333.33333333, 3000000., 9833333.33333333,
         -5000000.),
        (3000000., -12000000., 2000000., -2000000., -5000000., 14000000.),
    ])

    np.testing.assert_allclose(k_0_true, k_0)
    np.testing.assert_allclose(k_1_true, k_1)
Exemplo n.º 3
0
def test_compute_E_material():
    element_type = "triangle"
    mesh_path = "tests/data/msh/test.msh"
    load_condition = "plane stress"  # "plane stress" or "plane strain"
    steel = base.Material("steel", 3e7, 0.25, load_condition)

    mesh = meshio.read(mesh_path)
    num_elements = mesh.cells_dict[element_type].shape[0]
    material_map = mesh.cell_data_dict["gmsh:physical"][
        element_type] - 1  # element-material map
    E_material = base.compute_E_material(num_elements, material_map,
                                         mesh.field_data, steel)

    E_steel = np.array([
        (3.2e7, 8e6, 0.0),
        (8e6, 3.2e7, 0.0),
        (0.0, 0.0, 1.2e7),
    ])
    # TODO add aluminum matrix testing
    np.testing.assert_allclose(E_steel, E_material[0])
Exemplo n.º 4
0
def test_sparse_fem():
    mesh_path = "tests/data/msh/test.msh"

    element_type = "triangle"
    load_condition = "plane stress"  # "plane stress" or "plane strain"
    thickness = 0.5
    steel = base.Material("steel", 3e7, 0.25, load_condition)

    mesh = meshio.read(mesh_path)
    elements = mesh.cells_dict[element_type]
    nodal_coord = mesh.points[:, :2]
    num_elements = elements.shape[0]
    num_nodes = nodal_coord.shape[0]
    material_map = mesh.cell_data_dict["gmsh:physical"][
        element_type] - 1  # element-material map

    left_side = bc.DirichletBC("left side", mesh, [0, 1], 0.0)
    br_corner = bc.DirichletBC("bottom right corner", mesh, [1], 0.0)
    tr_corner = bc.NeumannBC("top right corner", mesh, [1], -1000.0)

    E_material = base.compute_E_material(num_elements, material_map,
                                         mesh.field_data, steel)
    K = sparse.csc_matrix((2 * num_nodes, 2 * num_nodes))
    R = np.zeros(num_nodes * 2)
    # for e in range(num_elements):
    #     K = base.sparse_assembly(K, e, mesh, E_material, thickness, element_type, integration_points)
    K = base.sp_assembly(K, num_elements, num_nodes, elements, nodal_coord,
                         material_map, E_material, thickness, element_type)

    print(K)
    K, R = bc.sp_apply_dirichlet(num_nodes, K, R, left_side, br_corner)
    R = bc.apply_neumann(R, tr_corner)

    D = linalg.spsolve(K, R)

    D_true = np.array([
        0.0, 0.0, 1.90773874e-05, 0.0, 8.73032981e-06, -7.41539125e-05, 0.0,
        0.0
    ])
    np.testing.assert_almost_equal(D_true, D)
Exemplo n.º 5
0
def test_feap_1():
    #LOGGING
    main_log = logging.getLogger(__name__)
    main_log.setLevel(logging.DEBUG)
    main_handler = logging.StreamHandler()  # main_log handler
    main_handler.setLevel(logging.DEBUG)
    main_formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )  # main_log formatter
    main_handler.setFormatter(main_formatter)
    main_log.addHandler(main_handler)

    feat_log = logging.getLogger("feat")
    feat_log.setLevel(logging.DEBUG)
    feat_handler = logging.StreamHandler()
    feat_handler.setLevel(logging.DEBUG)
    feat_formatter = logging.Formatter(
        '%(name)s - %(levelname)s - %(message)s')
    feat_handler.setFormatter(feat_formatter)
    feat_log.addHandler(feat_handler)

    # SETTINGS
    mesh_path = "tests/data/msh/feap_1.msh"
    main_log.info("MESH FILE: %s", mesh_path)

    # DATA
    element_type = "triangle"
    load_condition = "plane strain"  # "plane stress" or "plane strain"
    thickness = 1
    main_log.info("LOAD CONDITION: %s", load_condition)
    main_log.info("THICKNESS: %s", thickness)

    # MATERIAL
    cheese = base.Material("cheese", 70, 0.3, load_condition)  #FIXME
    main_log.info("MATERIALS: TODO")

    # MESH
    mesh = meshio.read(mesh_path)
    elements = mesh.cells_dict[element_type]
    nodal_coord = mesh.points[:, :2]
    print(type(nodal_coord))
    print(nodal_coord)
    num_elements = elements.shape[0]
    num_nodes = nodal_coord.shape[0]
    material_map = mesh.cell_data_dict["gmsh:physical"][
        element_type] - 1  # element-material map
    main_log.info("MESH INFO: %d elements, %d nodes", num_elements, num_nodes)

    # BOUNDARY CONDITIONS INSTANCES
    left_side = bc.DirichletBC("left side", mesh, [0], 0.0)
    bl_corner = bc.DirichletBC("bottom left corner", mesh, [1], 0.0)
    right_side = bc.DirichletBC("right side", mesh, [0], 1.0)
    main_log.info("BOUNDARY CONDITIONS: TODO")

    # ASSEMBLY
    E_material = base.compute_E_material(num_elements, material_map,
                                         mesh.field_data, cheese)
    K = np.zeros((num_nodes * 2, num_nodes * 2))
    R = np.zeros(num_nodes * 2)
    K = base.assembly(K, num_elements, elements, nodal_coord, material_map,
                      E_material, thickness, element_type)
    main_log.debug("STIFFNESS MATRIX (K) BEFORE BC:\n %s\n", K)

    # contrained dof rows of K are saved now
    reaction_dof = bc.dirichlet_dof(left_side, bl_corner)
    K_rows = K[reaction_dof, :]

    # BOUNDARY CONDITIONS APPLICATION
    K, R = bc.apply_dirichlet(K, R, left_side, bl_corner, right_side)
    main_log.debug("STIFFNESS MATRIX (K) AFTER BC:\n %s\n", K)
    main_log.debug("LOAD VECTOR (R) BEFORE BC:\n %s\n", R)

    # SOLVER
    D = np.linalg.solve(K, R)
    main_log.info("DISPLACEMENTS VECTOR (D):\n %s\n", D)

    reactions = np.dot(K_rows, D)
    main_log.debug("REACTIONS (dirichlet dofs):\n %s\n", reactions)
    modulus = base.compute_modulus(nodal_coord, right_side, reactions,
                                   thickness)
    main_log.info("RESULTING ELASTIC MODULUS: %f", modulus)

    comparable_dofs = [0, 1, 2, 4, 5, 6, 7]
    D_true = np.array([
        0.0,
        0.0,
        1.0,
        np.NaN,
        1.0,
        -4.28571429e-01,
        0.0,
        -4.28571429e-01,
    ])
    reactions_true = np.array(
        [-3.84615385e+01, -3.84615385e+01, -7.10542736e-15])

    np.testing.assert_allclose(reactions_true, reactions)
    np.testing.assert_allclose(D_true[comparable_dofs], D[comparable_dofs])
Exemplo n.º 6
0
def test_feap_2(poisson, D_true, reactions_true):
    # LOGGING
    main_log = logging.getLogger(__name__)
    main_log.setLevel(logging.DEBUG)
    main_handler = logging.StreamHandler()  # main_log handler
    main_handler.setLevel(logging.DEBUG)
    main_formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )  # main_log formatter
    main_handler.setFormatter(main_formatter)
    main_log.addHandler(main_handler)

    feat_log = logging.getLogger("feat")
    feat_log.setLevel(logging.DEBUG)
    feat_handler = logging.StreamHandler()
    feat_handler.setLevel(logging.DEBUG)
    feat_formatter = logging.Formatter(
        '%(name)s - %(levelname)s - %(message)s')
    feat_handler.setFormatter(feat_formatter)
    feat_log.addHandler(feat_handler)

    # SETTINGS
    mesh_path = "tests/data/msh/feap_2.msh"
    main_log.info("MESH FILE: %s", mesh_path)

    # DATA
    element_type = "triangle"
    load_condition = "plane strain"  # "plane stress" or "plane strain"
    thickness = 1
    main_log.info("LOAD CONDITION: %s", load_condition)
    main_log.info("THICKNESS: %s", thickness)

    # MATERIAL
    rubber = base.Material("rubber", 10, poisson, load_condition)  #FIXME
    main_log.info("MATERIALS: TODO")

    # MESH
    mesh = meshio.read(mesh_path)
    elements = mesh.cells_dict[element_type]
    nodal_coord = mesh.points[:, :2]
    num_elements = elements.shape[0]
    num_nodes = nodal_coord.shape[0]
    material_map = mesh.cell_data_dict["gmsh:physical"][
        element_type] - 1  # element-material map
    main_log.info("MESH INFO: %d elements, %d nodes", num_elements, num_nodes)

    # BOUNDARY CONDITIONS INSTANCES
    left_side = bc.DirichletBC("left side", mesh, [0], 0.0)
    b_corner = bc.DirichletBC("bottom corner", mesh, [1], 0.0)
    r_corner_x = bc.NeumannBC("right corner", mesh, [0], 0.4)
    r_corner_y = bc.NeumannBC("right corner", mesh, [1], 0.4)
    main_log.info("BOUNDARY CONDITIONS: TODO")

    # ASSEMBLY
    E_material = base.compute_E_material(num_elements, material_map,
                                         mesh.field_data, rubber)
    main_log.debug("E array:\n %s\n", E_material)
    K = np.zeros((num_nodes * 2, num_nodes * 2))
    R = np.zeros(num_nodes * 2)
    K = base.assembly(K, num_elements, elements, nodal_coord, material_map,
                      E_material, thickness, element_type)
    main_log.debug("STIFFNESS MATRIX (K) BEFORE BC:\n %s\n", K)

    # contrained dof rows of K are saved now
    reaction_dof = bc.dirichlet_dof(left_side, b_corner)
    K_rows = K[reaction_dof, :]

    # BOUNDARY CONDITIONS APPLICATION
    K, R = bc.apply_dirichlet(K, R, left_side, b_corner)
    R = bc.apply_neumann(R, r_corner_x, r_corner_y)
    main_log.debug("STIFFNESS MATRIX (K) AFTER BC:\n %s\n", K)
    main_log.debug("LOAD VECTOR (R) BEFORE BC:\n %s\n", R)

    # SOLVER
    D = np.linalg.solve(K, R)
    main_log.info("DISPLACEMENTS VECTOR (D):\n %s\n", D)

    reactions = np.dot(K_rows, D)
    main_log.debug("REACTIONS (dirichlet dofs):\n %s\n", reactions)

    np.testing.assert_allclose(D_true, D)
    np.testing.assert_allclose(reactions_true, reactions)