def test_plastic_centroid(): ## Test created in response to #114 # Since the section being tested is a compound geometry with two different # materials, this tests that the plastic centroid takes into account the # correct "center" of the original section which is affected by EA of each # of the constituent geometries. steel = Material( name="Steel", elastic_modulus=200e3, poissons_ratio=0.3, density=7.85e-6, yield_strength=500, color="grey", ) timber = Material( name="Timber", elastic_modulus=5e3, poissons_ratio=0.35, density=6.5e-7, yield_strength=20, color="burlywood", ) # create 310UB40.4 ub = i_section(d=304, b=165, t_f=10.2, t_w=6.1, r=11.4, n_r=8, material=steel) # create timber panel on top of the UB panel = rectangular_section(d=50, b=600, material=timber) panel = panel.align_center(ub).align_to(ub, on="top") # merge the two sections into one geometry object geometry = CompoundGeometry([ub, panel]) # create a mesh - use a mesh size of 5 for the UB, 20 for the panel geometry.create_mesh(mesh_sizes=[100, 100]) # create a Section object section = Section(geometry) # perform a geometric, warping and plastic analysis section.calculate_geometric_properties() section.calculate_plastic_properties() x_pc, y_pc = section.get_pc() assert x_pc == pytest.approx(82.5) assert y_pc == pytest.approx(250.360654576)
def test_rectangle(): fy = 500 E = 200e3 b = 50 d = 100 steel = Material( name="Steel", elastic_modulus=E, poissons_ratio=0.3, yield_strength=fy, density=8.05e-6, color="grey", ) Sx = b * d * d / 4 Mp = Sx * fy geom_mat = sections.rectangular_section(d=d, b=b, material=steel) geom_nomat = sections.rectangular_section(d=d, b=b) geom_mat.create_mesh(mesh_sizes=[2.5]) geom_nomat.create_mesh(mesh_sizes=[2.5]) sec_mat = Section(geom_mat) sec_nomat = Section(geom_nomat) sec_mat.calculate_geometric_properties() sec_mat.calculate_plastic_properties() sec_nomat.calculate_geometric_properties() sec_nomat.calculate_plastic_properties() assert sec_nomat.get_s()[0] == pytest.approx(Sx) assert sec_mat.get_s()[0] == pytest.approx(Mp) assert sec_mat.get_s()[0] / fy == sec_nomat.get_s()[0]
def test_multi_nested_compound_geometry_from_points(): """ Testing a multi-nested section. This section contains three nested materials in concentric square rings with a hole going through the center of the whole section. This test confirms that the section can be successfully built using .from_points, that the control_points and hole nodes persist in the right locations, and that the plastic section calculation raises a warning because the nested regions overlap. """ points = [ [-50.0, 50.0], [50.0, 50.0], [50.0, -50.0], [-50.0, -50.0], [37.5, -37.5], [37.5, 37.5], [-37.5, 37.5], [-37.5, -37.5], [25.0, -25.0], [25.0, 25.0], [-25.0, 25.0], [-25.0, -25.0], [12.5, -12.5], [12.5, 12.5], [-12.5, 12.5], [-12.5, -12.5], ] facets = [ [0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [8, 9], [9, 10], [10, 11], [11, 8], [12, 13], [13, 14], [14, 15], [15, 12], ] control_points = [[-43.75, 0.0], [-31.25, 0.0], [-18.75, 0.0]] holes = [[0, 0]] mat1 = Material( name="mat1", elastic_modulus=2, poissons_ratio=0.3, density=1e-6, yield_strength=5, color="grey", ) mat2 = Material( name="mat2", elastic_modulus=5, poissons_ratio=0.2, density=2e-6, yield_strength=10, color="blue", ) mat3 = Material( name="mat3", elastic_modulus=1, poissons_ratio=0.25, density=1.5e-6, yield_strength=3, color="green", ) materials = [mat1, mat2, mat3] nested_compound = CompoundGeometry.from_points( points=points, facets=facets, control_points=control_points, holes=holes, materials=materials, ) wkt_test_geom = shapely.wkt.loads( "MULTIPOLYGON (((50 50, 50 -50, -50 -50, -50 50, 50 50), (12.5 12.5, -12.5 12.5, -12.5 -12.5, 12.5 -12.5, 12.5 12.5)), ((-37.5 -37.5, -37.5 37.5, 37.5 37.5, 37.5 -37.5, -37.5 -37.5), (12.5 12.5, -12.5 12.5, -12.5 -12.5, 12.5 -12.5, 12.5 12.5)), ((-25 -25, -25 25, 25 25, 25 -25, -25 -25), (12.5 12.5, -12.5 12.5, -12.5 -12.5, 12.5 -12.5, 12.5 12.5)))" ) assert (nested_compound.geom - wkt_test_geom) == Polygon() assert nested_compound.control_points == [ (-43.75, 0.0), (-31.25, 0.0), (-18.75, 0.0), ] assert nested_compound.holes == [(0, 0)] # test materials for idx, geom in enumerate(nested_compound.geoms): assert geom.material == materials[idx] # Section contains overlapping geometries which will result in potentially incorrect # plastic properties calculation (depends on user intent and geometry). # Test to ensure a warning is raised about this to notify the user. nested_compound.create_mesh([25, 30, 35]) nested_compound_sec = Section(nested_compound) nested_compound_sec.calculate_geometric_properties() with pytest.warns(UserWarning): nested_compound_sec.calculate_plastic_properties()
) from shapely import wkt import json big_sq = rectangular_section(d=300, b=250) small_sq = rectangular_section(d=100, b=75) small_hole = rectangular_section(d=40, b=30).align_center(small_sq) i_sec = i_section(d=200, b=100, t_f=20, t_w=10, r=12, n_r=12) small_sq_w_hole = small_sq - small_hole composite = (big_sq + small_sq_w_hole.align_to( big_sq, on="top", inner=True).align_to(big_sq, on="top") + i_sec.align_to( big_sq, on="bottom", inner=True).align_to(big_sq, on="right")) composite.create_mesh([200]) comp_sec = Section(composite) comp_sec.calculate_geometric_properties() comp_sec.calculate_plastic_properties() # Subtractive modelling nested_geom = (small_sq - small_hole) + small_hole nested_geom.create_mesh([50]) nested_sec = Section(nested_geom) # Overlapped modelling overlay_geom = small_sq + small_hole overlay_geom.create_mesh([50]) overlay_sec = Section(overlay_geom) steel = Material("steel", 200e3, 0.3, 7.85e-6, 400, "grey") def test_material_persistence():
# %% # Mirror the 200 PFC about the y-axis pfc1 = pfc1.mirror_section(axis="y", mirror_point=[0, 0]) # %% # Merge the pfc sections geometry = ((pfc1 - pfc2) | pfc1) + pfc2 # %% # Rotate the geometry counter-clockwise by 30 degrees geometry = geometry.rotate_section(angle=30) geometry.plot_geometry() # %% # Create a mesh and section. For the mesh, use a mesh size of 5 for the 200PFC # and 4 for the 150PFC geometry.create_mesh(mesh_sizes=[5, 4]) section = Section(geometry, time_info=True) section.display_mesh_info() # display the mesh information section.plot_mesh() # plot the generated mesh # %% # Perform a geometric, warping and plastic analysis, displaying the time info # and the iteration info for the plastic analysis section.calculate_geometric_properties() section.calculate_warping_properties() section.calculate_plastic_properties(verbose=True) section.plot_centroids()
# %% # Create a 50 diameter circle discretised by 64 points geometry = sections.circular_section(d=50, n=64) geometry.plot_geometry() # %% # Create a mesh with a mesh size of 2.5 and display information about it geometry.create_mesh(mesh_sizes=[2.5]) section = Section(geometry, time_info=True) section.display_mesh_info() section.plot_mesh() # %% # perform a geometric, warping and plastic analysis, displaying the time info section.calculate_geometric_properties() section.calculate_warping_properties() section.calculate_plastic_properties() # %% # Print the results to the terminal section.display_results() # %% # Get and print the second moments of area and the torsion constant (ixx_c, iyy_c, ixy_c) = section.get_ic() j = section.get_j() print("Ixx + Iyy = {0:.3f}".format(ixx_c + iyy_c)) print("J = {0:.3f}".format(j))
import pytest_check as check from shapely.geometry import Polygon from sectionproperties.pre.geometry import Geometry import sectionproperties.pre.library.primitive_sections as sections import sectionproperties.pre.library.steel_sections as steel_sections from sectionproperties.analysis.section import Section from sectionproperties.tests.helper_functions import validate_properties # Setup for angle section angle = steel_sections.angle_section(d=150, b=90, t=12, r_r=10, r_t=5, n_r=8) angle.create_mesh(mesh_sizes=2.5) angle_section = Section(angle) angle_section.calculate_geometric_properties() angle_section.calculate_plastic_properties() angle_section.calculate_warping_properties() def test_angle_all_properties(): check.almost_equal(angle_section.section_props.area, 2747.059) check.almost_equal(angle_section.section_props.perimeter, 471.3501) check.almost_equal(angle_section.section_props.cx, 2.122282e1) check.almost_equal(angle_section.section_props.cy, 5.098127e1) check.almost_equal(angle_section.section_props.ixx_g, 1.342632e7) check.almost_equal(angle_section.section_props.iyy_g, 2.955753e6) check.almost_equal(angle_section.section_props.ixy_g, 1.086603e6) check.almost_equal(angle_section.section_props.ixx_c, 6.286470e6) check.almost_equal(angle_section.section_props.iyy_c, 1.718455e6) check.almost_equal(angle_section.section_props.ixy_c, -1.885622e6) check.almost_equal(angle_section.section_props.zxx_plus, 6.348769e4) check.almost_equal(angle_section.section_props.zxx_minus, 1.233094e5)
# import unittest import sectionproperties.pre.library.primitive_sections as primitive_sections import sectionproperties.pre.pre as pre from sectionproperties.analysis.section import Section from sectionproperties.tests.helper_functions import validate_properties import sectionproperties.analysis.section as file # Rectangle section setup rectangle_geometry = primitive_sections.rectangular_section(b=50, d=100) rectangle_geometry.create_mesh(mesh_sizes=100) rectangle_section = Section(rectangle_geometry) rectangle_section.calculate_geometric_properties() rectangle_section.calculate_warping_properties() rectangle_section.calculate_plastic_properties() tol = 1e-6 warp_tol = 1e-4 def test_rectangular_section_geometric(): check.almost_equal(rectangle_section.section_props.area, 100 * 50, rel=tol) check.almost_equal(rectangle_section.section_props.perimeter, 2 * 100 + 2 * 50, rel=tol) check.almost_equal(rectangle_section.section_props.mass, 1 * 100 * 50, rel=tol) check.almost_equal(rectangle_section.section_props.ea, 1 * 100 * 50,