Exemplo n.º 1
0
def get_properties():

    # build the lists of points, facets, holes and control points
    points = request.json['points']
    facets = request.json['facets']
    holes = request.json['holes']
    control_points = request.json['controls']

    # create the custom geometry object
    geometry = sections.CustomSection(points, facets, holes, control_points)
    geometry.clean_geometry()  # clean the geometry

    # create the mesh - use a smaller refinement for the angle region
    mesh = geometry.create_mesh(mesh_sizes=[0.0005, 0.001])

    # create a CrossSection object
    section = CrossSection(geometry, mesh)

    # perform a geometric, warping and plastic analysis
    section.calculate_geometric_properties()
    section.calculate_warping_properties()
    section.calculate_plastic_properties()

    properties = section.display_results()

    return jsonify({'properties': properties})
Exemplo n.º 2
0
    def sec_cal(self, mesh=0.01, d=0.03):
        """
        对单个截面进行属性计算
        :param mesh: 截面划分单元尺寸
        :param d: 截取形心附近应力范围
        :return: 无
        """

        self.geo = sections.CustomSection(self.ids, self.faces,
                                          self.points[1:], [self.points[0]])
        self.mesh = self.geo.create_mesh(mesh_sizes=[mesh])
        self.sec = CrossSection(self.geo, self.mesh)
        self.sec.plot_mesh()
        self.sec.calculate_geometric_properties()
        self.sec.calculate_warping_properties()

        # 获取截面属性
        prop = self.sec.section_props
        self.prop['center'] = self.sec.get_c()
        self.ids_to_c = [i - self.prop['center'] for i in self.ids_sep]
        self.prop['area'] = prop.area
        self.prop['as'] = [prop.A_s22, prop.A_s11]
        self.prop['i'] = [prop.j, prop.ixx_c, prop.iyy_c]
        pts = np.array(self.ids)
        left = prop.cx - pts[:, 0].min()
        right = pts[:, 0].max() - prop.cx
        top = pts[:, 1].max() - prop.cy
        bot = prop.cy - pts[:, 1].min()
        self.prop['c'] = [right, left, top, bot]

        self.stress = self.sec.calculate_stress(Vx=1, Vy=1)
        stresses = self.stress.get_stress()
        dy = self.sec.get_c()[1] - self.sec.mesh_nodes[:, 1]
        dx = self.sec.get_c()[0] - self.sec.mesh_nodes[:, 0]
        qyb = stresses[0]['sig_zy_vy'][dx < d].max() * prop.ixx_c
        qzb = stresses[0]['sig_zx_vx'][dy < d].max() * prop.iyy_c
        self.prop['q'] = [qyb, qzb]
        self.prop['p'] = [
            self.pls[0].length,
            sum([i.length for i in self.pls[1:]])
        ]

        # 获取角点
        pt_all = self.ids_to_c[0]
        pt_1 = pt_all[(pt_all[:, 0] < 0) & (pt_all[:, 1] > 0)]
        pt_2 = pt_all[(pt_all[:, 0] > 0) & (pt_all[:, 1] > 0)]
        pt_3 = pt_all[(pt_all[:, 0] < 0) & (pt_all[:, 1] < 0)]
        pt_4 = pt_all[(pt_all[:, 0] > 0) & (pt_all[:, 1] < 0)]
        pt_1 = find_pt(pt_1, relation='max')
        pt_2 = find_pt(pt_2, relation='max')
        pt_3 = find_pt(pt_3, relation='max')
        pt_4 = find_pt(pt_4, relation='max')
        self.corner = [pt_1, pt_2, pt_4, pt_3]
Exemplo n.º 3
0
    def update_section(self, section):
        self.section = section

        self.debug(f'determining {section} properties...')
        if isinstance(self.section, sectionproperties.pre.sections.Geometry):
            self.debug(f'determining mesh {section} properties...')
            mesh = self.section.create_mesh([self.mesh_size])
            self._section_properties = CrossSection(self.section,
                                                    mesh)  #no material here
            self._section_properties.calculate_geometric_properties()
            self._section_properties.calculate_warping_properties()

        elif isinstance(self.section, ottgeo.Profile2D):
            self.debug(f'determining profile {section} properties...')
            self._section_properties = self.section

        else:
            self.debug(f'checking input values')
            assert all([
                val is not None
                for val in (self.in_Iy, self.in_Ix, self.in_J, self.in_A)
            ])
    def test_angle(self):
        """Section properties are validated against results from the Strand7
        beam section utility."""

        geometry = sections.AngleSection(d=150,
                                         b=90,
                                         t=12,
                                         r_r=10,
                                         r_t=5,
                                         n_r=8)
        mesh = geometry.create_mesh(mesh_sizes=[2.5])

        section = CrossSection(geometry, mesh)

        val_list = []
        val_list.append({"prop": "area", "val": 2746.73, "tol": 2e-4})
        val_list.append({"prop": "perimeter", "val": 471, "tol": 1e-3})
        val_list.append({"prop": "cx", "val": 21.2255, "tol": 2e-4})
        val_list.append({"prop": "cy", "val": 50.9893, "tol": 2e-4})
        val_list.append({"prop": "ixx_g", "val": 1.3428e7, "tol": 2e-4})
        val_list.append({"prop": "iyy_g", "val": 2.95629e6, "tol": 2e-4})
        val_list.append({"prop": "ixy_g", "val": 1.08669e6, "tol": 2e-4})
        val_list.append({"prop": "ixx_c", "val": 6.28678e6, "tol": 2e-4})
        val_list.append({"prop": "iyy_c", "val": 1.71882e6, "tol": 3e-4})
        val_list.append({"prop": "ixy_c", "val": -1.88603e6, "tol": 3e-4})
        val_list.append({"prop": "zxx_plus", "val": 63496.0, "tol": 2e-4})
        val_list.append({"prop": "zxx_minus", "val": 123296, "tol": 2e-4})
        val_list.append({"prop": "zyy_plus", "val": 24992.1, "tol": 3e-4})
        val_list.append({"prop": "zyy_minus", "val": 80979.0, "tol": 2e-4})
        val_list.append({"prop": "rx", "val": 47.8416, "tol": 2e-4})
        val_list.append({"prop": "ry", "val": 25.0154, "tol": 2e-4})
        val_list.append({"prop": "i11_c", "val": 6.96484e6, "tol": 2e-4})
        val_list.append({"prop": "i22_c", "val": 1.04076e6, "tol": 2e-4})
        val_list.append({"prop": "phi", "val": 19.7744 - 180, "tol": 2e-4})
        val_list.append({"prop": "z11_plus", "val": 97751.9, "tol": 2e-4})
        val_list.append({"prop": "z11_minus", "val": 69403.3, "tol": 2e-4})
        val_list.append({"prop": "z22_plus", "val": 27959.0, "tol": 2e-4})
        val_list.append({"prop": "z22_minus", "val": 20761.6, "tol": 3e-4})
        val_list.append({"prop": "r11", "val": 50.3556, "tol": 2e-4})
        val_list.append({"prop": "r22", "val": 19.4656, "tol": 2e-4})
        val_list.append({"prop": "sxx", "val": 113541, "tol": 2e-4})
        val_list.append({"prop": "syy", "val": 45724.6, "tol": 2e-4})
        val_list.append({
            "prop": "sf_xx_plus",
            "val": 113541 / 63496.0,
            "tol": 2e-4
        })
        val_list.append({
            "prop": "sf_xx_minus",
            "val": 113541 / 123296,
            "tol": 2e-4
        })
        val_list.append({
            "prop": "sf_yy_plus",
            "val": 45724.6 / 24992.1,
            "tol": 3e-4
        })
        val_list.append({
            "prop": "sf_yy_minus",
            "val": 45724.6 / 80979.0,
            "tol": 2e-4
        })
        val_list.append({"prop": "s11", "val": 121030, "tol": 2e-4})
        val_list.append({"prop": "s22", "val": 43760.6, "tol": 2e-4})
        val_list.append({
            "prop": "sf_11_plus",
            "val": 121030 / 97751.9,
            "tol": 2e-4
        })
        val_list.append({
            "prop": "sf_11_minus",
            "val": 121030 / 69403.3,
            "tol": 2e-4
        })
        val_list.append({
            "prop": "sf_22_plus",
            "val": 43760.6 / 27959.0,
            "tol": 2e-4
        })
        val_list.append({
            "prop": "sf_22_minus",
            "val": 43760.6 / 20761.6,
            "tol": 3e-4
        })
        val_list.append({"prop": "j", "val": 135333, "tol": 1e-3})
        val_list.append({"prop": "gamma", "val": 1.62288e8, "tol": 5e-4})
        val_list.append({"prop": "A_s11", "val": 885.444, "tol": 2e-4})
        val_list.append({"prop": "A_s22", "val": 1459.72, "tol": 4e-4})
        val_list.append({"prop": "x11_se", "val": 28.719, "tol": 1e-3})
        val_list.append({"prop": "y22_se", "val": 35.2348, "tol": 5e-4})

        section.calculate_geometric_properties()
        section.calculate_plastic_properties()
        section.calculate_warping_properties()

        validate_properties(self, val_list, section)
    def test_custom(self):
        """Section properties are validated against results from the Strand7
        beam section utility."""

        points = [[-10, 0], [110, 0], [100, 10], [55, 10], [55, 90], [100, 90],
                  [110, 100], [110, 110], [-10, 110], [-10, 100], [0, 90],
                  [45, 90], [45, 10], [-10, 10]]
        facets = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6,
                                                                   7], [7, 8],
                  [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 0]]
        holes = []
        control_points = [[0, 5]]

        geometry = sections.CustomSection(points, facets, holes,
                                          control_points)
        mesh = geometry.create_mesh(mesh_sizes=[5])
        section = CrossSection(geometry, mesh)

        val_list = []
        val_list.append({"prop": "area", "val": 4250, "tol": None})
        val_list.append({"prop": "cx", "val": 49.3333, "tol": None})
        val_list.append({"prop": "cy", "val": 65.0196, "tol": None})
        val_list.append({"prop": "ixx_g", "val": 2.56725e7, "tol": None})
        val_list.append({"prop": "iyy_g", "val": 1.41858e7, "tol": None})
        val_list.append({"prop": "ixy_g", "val": 1.37979e7, "tol": None})
        val_list.append({"prop": "ixx_c", "val": 7.70542e6, "tol": None})
        val_list.append({"prop": "iyy_c", "val": 3.84228e6, "tol": None})
        val_list.append({"prop": "ixy_c", "val": 165472, "tol": None})
        val_list.append({"prop": "zxx_plus", "val": 171306, "tol": None})
        val_list.append({"prop": "zxx_minus", "val": 118509, "tol": None})
        val_list.append({"prop": "zyy_plus", "val": 63334.2, "tol": None})
        val_list.append({"prop": "zyy_minus", "val": 64757.5, "tol": None})
        val_list.append({"prop": "rx", "val": 42.5798, "tol": None})
        val_list.append({"prop": "ry", "val": 30.0677, "tol": None})
        val_list.append({"prop": "phi", "val": 177.552 - 180, "tol": 1e-4})
        val_list.append({"prop": "i11_c", "val": 7.71249e6, "tol": None})
        val_list.append({"prop": "i22_c", "val": 3.8352e6, "tol": None})
        val_list.append({"prop": "z11_plus", "val": 162263, "tol": None})
        val_list.append({"prop": "z11_minus", "val": 114268, "tol": None})
        val_list.append({"prop": "z22_plus", "val": 60503.0, "tol": None})
        val_list.append({"prop": "z22_minus", "val": 62666.1, "tol": None})
        val_list.append({"prop": "r11", "val": 42.5993, "tol": None})
        val_list.append({"prop": "r22", "val": 30.04, "tol": None})
        val_list.append({"prop": "sxx", "val": 153196, "tol": None})
        val_list.append({"prop": "syy", "val": 101494, "tol": None})
        val_list.append({
            "prop": "sf_xx_plus",
            "val": 153196 / 171306,
            "tol": None
        })
        val_list.append({
            "prop": "sf_xx_minus",
            "val": 153196 / 118509,
            "tol": None
        })
        val_list.append({
            "prop": "sf_yy_plus",
            "val": 101494 / 63334.2,
            "tol": None
        })
        val_list.append({
            "prop": "sf_yy_minus",
            "val": 101494 / 64757.5,
            "tol": None
        })
        val_list.append({"prop": "s11", "val": 153347, "tol": None})
        val_list.append({"prop": "s22", "val": 101501, "tol": None})
        val_list.append({
            "prop": "sf_11_plus",
            "val": 153347 / 162263,
            "tol": None
        })
        val_list.append({
            "prop": "sf_11_minus",
            "val": 153347 / 114268,
            "tol": None
        })
        val_list.append({
            "prop": "sf_22_plus",
            "val": 101501 / 60503.0,
            "tol": None
        })
        val_list.append({
            "prop": "sf_22_minus",
            "val": 101501 / 62666.1,
            "tol": None
        })
        val_list.append({"prop": "j", "val": 347040, "tol": 5e-3})
        val_list.append({"prop": "gamma", "val": 7.53539e9, "tol": 1e-3})
        val_list.append({"prop": "A_s11", "val": 2945.53, "tol": 5e-4})
        val_list.append({"prop": "A_s22", "val": 956.014, "tol": 5e-4})
        val_list.append({"prop": "x11_se", "val": 1.9134, "tol": 5e-3})
        val_list.append({"prop": "y22_se", "val": 3.02028, "tol": 5e-3})

        section.calculate_geometric_properties()
        section.calculate_plastic_properties()
        section.calculate_warping_properties()

        validate_properties(self, val_list, section)
class TestRectangle(unittest.TestCase):
    """Section properties are mostly validated against hand calcs. Results from
    Strand7 and Roark's Formulas for Stress and Strain are used for some
    warping properties."""
    def setUp(self):
        self.geometry = sections.RectangularSection(d=100, b=50)
        self.mesh = self.geometry.create_mesh(mesh_sizes=[10])
        self.section = CrossSection(self.geometry, self.mesh)

    def test_geometric(self):
        self.section.calculate_geometric_properties()

        val_list = []
        val_list.append({"prop": "area", "val": 100 * 50, "tol": None})
        val_list.append({
            "prop": "perimeter",
            "val": 100 * 2 + 50 * 2,
            "tol": None
        })
        val_list.append({"prop": "ea", "val": 1 * 100 * 50, "tol": None})
        val_list.append({"prop": "qx", "val": 100 * 50 * 50, "tol": None})
        val_list.append({"prop": "qy", "val": 100 * 50 * 25, "tol": None})
        val_list.append({"prop": "ixx_g", "val": 50 * 100**3 / 3, "tol": None})
        val_list.append({"prop": "iyy_g", "val": 100 * 50**3 / 3, "tol": None})
        val_list.append({
            "prop": "ixy_g",
            "val": 100 * 50 * 50 * 25,
            "tol": None
        })
        val_list.append({"prop": "cx", "val": 50 / 2, "tol": None})
        val_list.append({"prop": "cy", "val": 100 / 2, "tol": None})
        val_list.append({
            "prop": "ixx_c",
            "val": 50 * 100**3 / 12,
            "tol": None
        })
        val_list.append({
            "prop": "iyy_c",
            "val": 100 * 50**3 / 12,
            "tol": None
        })
        val_list.append({"prop": "ixy_c", "val": 0, "tol": None})
        val_list.append({
            "prop": "zxx_plus",
            "val": 50 * 100**2 / 6,
            "tol": None
        })
        val_list.append({
            "prop": "zxx_minus",
            "val": 50 * 100**2 / 6,
            "tol": None
        })
        val_list.append({
            "prop": "zyy_plus",
            "val": 100 * 50**2 / 6,
            "tol": None
        })
        val_list.append({
            "prop": "zyy_minus",
            "val": 100 * 50**2 / 6,
            "tol": None
        })
        val_list.append({
            "prop": "rx",
            "val": (50 * 100**3 / 12 / 100 / 50)**0.5,
            "tol": None
        })
        val_list.append({
            "prop": "ry",
            "val": (100 * 50**3 / 12 / 100 / 50)**0.5,
            "tol": None
        })
        val_list.append({
            "prop": "i11_c",
            "val": 50 * 100**3 / 12,
            "tol": None
        })
        val_list.append({
            "prop": "i22_c",
            "val": 100 * 50**3 / 12,
            "tol": None
        })
        val_list.append({"prop": "phi", "val": 0, "tol": None})
        val_list.append({
            "prop": "z11_plus",
            "val": 50 * 100**2 / 6,
            "tol": None
        })
        val_list.append({
            "prop": "z11_minus",
            "val": 50 * 100**2 / 6,
            "tol": None
        })
        val_list.append({
            "prop": "z22_plus",
            "val": 100 * 50**2 / 6,
            "tol": None
        })
        val_list.append({
            "prop": "z22_minus",
            "val": 100 * 50**2 / 6,
            "tol": None
        })
        val_list.append({
            "prop": "r11",
            "val": (50 * 100**3 / 12 / 100 / 50)**0.5,
            "tol": None
        })
        val_list.append({
            "prop": "r22",
            "val": (100 * 50**3 / 12 / 100 / 50)**0.5,
            "tol": None
        })

        validate_properties(self, val_list, self.section)

    def test_plastic(self):
        self.section.calculate_geometric_properties()
        self.section.calculate_plastic_properties()

        val_list = []
        val_list.append({"prop": "x_pc", "val": 50 / 2, "tol": None})
        val_list.append({"prop": "y_pc", "val": 100 / 2, "tol": None})
        val_list.append({"prop": "x11_pc", "val": 50 / 2, "tol": None})
        val_list.append({"prop": "y22_pc", "val": 100 / 2, "tol": None})
        val_list.append({"prop": "sxx", "val": 50 * 100**2 / 4, "tol": None})
        val_list.append({"prop": "syy", "val": 100 * 50**2 / 4, "tol": None})
        val_list.append({"prop": "s11", "val": 50 * 100**2 / 4, "tol": None})
        val_list.append({"prop": "s22", "val": 100 * 50**2 / 4, "tol": None})
        val_list.append({"prop": "sf_xx_plus", "val": 1.5, "tol": None})
        val_list.append({"prop": "sf_xx_minus", "val": 1.5, "tol": None})
        val_list.append({"prop": "sf_yy_plus", "val": 1.5, "tol": None})
        val_list.append({"prop": "sf_yy_minus", "val": 1.5, "tol": None})
        val_list.append({"prop": "sf_11_plus", "val": 1.5, "tol": None})
        val_list.append({"prop": "sf_11_minus", "val": 1.5, "tol": None})
        val_list.append({"prop": "sf_22_plus", "val": 1.5, "tol": None})
        val_list.append({"prop": "sf_22_minus", "val": 1.5, "tol": None})

        validate_properties(self, val_list, self.section)

    def test_warping(self):
        self.section.calculate_geometric_properties()
        self.section.calculate_warping_properties()

        val_list = []
        val_list.append({"prop": "j", "val": 2861002, "tol": 0.04})  # roark's
        val_list.append({"prop": "j", "val": 2.85852e6, "tol": 2e-5})  # st7
        val_list.append({
            "prop": "gamma",
            "val": 3.17542e8,
            "tol": None
        })  # st7
        val_list.append({"prop": "x_se", "val": 50 / 2, "tol": None})
        val_list.append({"prop": "y_se", "val": 100 / 2, "tol": None})
        val_list.append({"prop": "x11_se", "val": 0, "tol": None})
        val_list.append({"prop": "y22_se", "val": 0, "tol": None})
        val_list.append({"prop": "x_st", "val": 50 / 2, "tol": None})
        val_list.append({"prop": "y_st", "val": 100 / 2, "tol": None})
        val_list.append({"prop": "A_sx", "val": 5 / 6 * 100 * 50, "tol": None})
        val_list.append({"prop": "A_sy", "val": 5 / 6 * 100 * 50, "tol": None})
        val_list.append({
            "prop": "A_s11",
            "val": 5 / 6 * 100 * 50,
            "tol": None
        })
        val_list.append({
            "prop": "A_s22",
            "val": 5 / 6 * 100 * 50,
            "tol": None
        })
 def setUp(self):
     self.geometry = sections.RectangularSection(d=100, b=50)
     self.mesh = self.geometry.create_mesh(mesh_sizes=[10])
     self.section = CrossSection(self.geometry, self.mesh)
import sectionproperties.pre.sections as sections
from sectionproperties.analysis.cross_section import CrossSection

# create a 50 diameter circle discretised by 64 points
geometry = sections.CircularSection(d=50, n=64)
geometry.plot_geometry()  # plot the geometry

# create a mesh with a mesh size of 2.5
mesh = geometry.create_mesh(mesh_sizes=[2.5])

section = CrossSection(geometry, mesh)  # create a CrossSection object
section.display_mesh_info()  # display the mesh information
section.plot_mesh()  # plot the generated mesh

# perform a geometric, warping and plastic anaylsis, displaying the time info
section.calculate_geometric_properties(time_info=True)
section.calculate_warping_properties(time_info=True)
section.calculate_plastic_properties(time_info=True)

# print the results to the terminal
section.display_results()

# get the second moments of area and the torsion constant
(ixx_c, iyy_c, ixy_c) = section.get_ic()
j = section.get_j()

# print the sum of the second moments of area and the torsion constant
print("Ixx + Iyy = {0:.3f}".format(ixx_c + iyy_c))
print("J = {0:.3f}".format(j))
Exemplo n.º 9
0
    def calculate(self, loadProfileFromDB):
        '''Se ejecuta el calculo de las propiedades de la seccion.

        Referencia
        ----------
            rx, ry : radio de giro del miembro | sqrt(I/A)
            c_i : coordenada del centroide de la seccion
            sc_i : coordenada del centro de corte
            A : Area de la seccion
            Cw : Constante torsional de warping de la seccion
            J : Constante de torsion de St. Venant
            Si : modulo elastico
            j : mitad de la constante monociclica a compresion en eje -y- (beta22-)

        '''
        if loadProfileFromDB:
            try:
                self.load()
            except:
                loadProfileFromDB = False
                pass
        if not loadProfileFromDB:
            ## CALCULO PROPIEDADES A PARTIR DEL PAQUETE sectionproperties
            geometry = sections.CeeSection(d=self.H, b=self.B+self.r_out, l=self.r_out, t=self.t, r_out=self.r_out, n_r=8)
            # corto los labios y el radio
            p1 = geometry.add_point([self.B, 0])
            p2 = geometry.add_point([self.B, self.t])
            p3 = geometry.add_point([self.B, self.H])
            p4 = geometry.add_point([self.B, self.H-self.t])

            geometry.add_facet([p1, p2])
            geometry.add_facet([p3, p4])
            geometry.add_hole([self.B+self.r_out/10, self.t/2])  # add hole
            geometry.add_hole([self.B+self.r_out/10, self.H-self.t/2])  # add hole
            geometry.clean_geometry()  # clean the geometry
            # create mesh
            mesh = geometry.create_mesh(mesh_sizes=[self.t/4.0])
            # creo la seccion
            section = CrossSection(geometry, mesh)
            # calculo las propiedades
            section.calculate_geometric_properties()
            section.calculate_warping_properties()

            (self.c_x, self.c_y) = section.get_c() # centroides
            (self.sc_x, self.sc_y) = section.get_sc() # shear center
            self.Cw = section.get_gamma() # warping
            (self.rx, self.ry) = section.get_rc() # radios de giro
            self.J = section.get_j()
            self.A = section.get_area()
            self.Ae = section.get_area()
            (self.Ix, self.Iy, _) = section.get_ic()
            (self.Sx, _, _, _) = section.get_z()    # modulo elastico
            self.j = section.get_beta_p()[3]/2.0

            self.save(section)

            self.section = section
Exemplo n.º 10
0
# mirror the 200 PFC about the y-axis
pfc1.mirror_section(axis='y', mirror_point=[0, 0])

# merge the pfc sections
geometry = sections.MergedSection([pfc1, pfc2])

# rotate the geometry counter-clockwise by 30 degrees
geometry.rotate_section(angle=30)

# clean the geometry - print cleaning information to the terminal
geometry.clean_geometry(verbose=True)
geometry.plot_geometry()  # plot the geometry

# create a mesh - use a mesh size of 5 for the 200PFC and 4 for the 150PFC
mesh = geometry.create_mesh(mesh_sizes=[5, 4])

# create a CrossSection object
section = CrossSection(geometry, mesh)
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(time_info=True)
section.calculate_warping_properties(time_info=True)
section.calculate_plastic_properties(time_info=True, verbose=True)

# plot the centroids
section.plot_centroids()
from sectionproperties.analysis.cross_section import CrossSection

# define mesh sizes
mesh_size_list = [50, 20, 10, 5, 3, 2, 1]
nr_list = [4, 8, 12, 16, 20, 24, 32, 64]

# initialise result lists
mesh_results = []
mesh_elements = []
nr_results = []
nr_elements = []

# calculate reference solution
geometry = sections.ISection(d=203, b=133, t_f=7.8, t_w=5.8, r=8.9, n_r=64)
mesh = geometry.create_mesh(mesh_sizes=[0.5])  # create mesh
section = CrossSection(geometry, mesh)  # create a CrossSection object
section.calculate_geometric_properties()
section.calculate_warping_properties()
j_reference = section.get_j()  # get the torsion constant

# run through mesh_sizes with n_r = 16
for mesh_size in mesh_size_list:
    geometry = sections.ISection(d=203, b=133, t_f=7.8, t_w=5.8, r=8.9, n_r=16)
    mesh = geometry.create_mesh(mesh_sizes=[mesh_size])  # create mesh
    section = CrossSection(geometry, mesh)  # create a CrossSection object
    section.calculate_geometric_properties()
    section.calculate_warping_properties()

    mesh_elements.append(len(section.elements))
    mesh_results.append(section.get_j())
t = 0.1

# build the lists of points, facets, holes and control points
points = [
    [-t / 2, -2 * a], [t / 2, -2 * a], [t / 2, -t / 2], [a, -t / 2], [a, t / 2], [-t / 2, t / 2],
    [-b / 2, -2 * a], [b / 2, -2 * a], [b / 2, -2 * a - t], [-b / 2, -2 * a - t]
]
facets = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0], [6, 7], [7, 8], [8, 9], [9, 6]]
holes = []
control_points = [[0, 0], [0, -2 * a - t / 2]]

# create the custom geometry object
geometry = sections.CustomSection(points, facets, holes, control_points)
geometry.clean_geometry()  # clean the geometry
geometry.plot_geometry()  # plot the geometry

# create the mesh - use a smaller refinement for the angle region
mesh = geometry.create_mesh(mesh_sizes=[0.0005, 0.001])

# create a CrossSection object
section = CrossSection(geometry, mesh)
section.plot_mesh()  # plot the generated mesh

# perform a geometric, warping and plastic analysis
section.calculate_geometric_properties()
section.calculate_warping_properties()
section.calculate_plastic_properties()

# plot the centroids
section.plot_centroids()
import matplotlib.pyplot as plt
import sectionproperties.pre.sections as sections
from sectionproperties.analysis.cross_section import CrossSection

# create a rectangular section
geometry = sections.RectangularSection(d=100, b=50)

# create a list of mesh sizes to analyse
mesh_sizes = [1.5, 2, 2.5, 3, 4, 5, 10, 15, 20, 25, 30, 40, 50, 75, 100]
j_calc = []  # list to store torsion constants
t_calc = []  # list to store computation times

# loop through mesh sizes
for mesh_size in mesh_sizes:
    mesh = geometry.create_mesh(mesh_sizes=[mesh_size])  # create mesh
    section = CrossSection(geometry, mesh)  # create a CrossSection object
    start_time = time.time()  # start timing
    # calculate the frame properties
    (_, _, _, _, j, _) = section.calculate_frame_properties()
    t = time.time() - start_time  # stop timing
    t_calc.append(t)  # save the time
    j_calc.append(j)  # save the torsion constant
    # print the result
    str = "Mesh Size: {0}; ".format(mesh_size)
    str += "Solution Time {0:.5f} s; ".format(t)
    str += "Torsion Constant: {0:.12e}".format(j)
    print(str)

correct_val = j_calc[0]  # assume the finest mesh gives the 'correct' value
j_np = np.array(j_calc)  # convert results to a numpy array
error_vals = (j_calc - correct_val) / j_calc * 100  # compute the error
Exemplo n.º 14
0
def boxgenerator(b, d, t_w, t_f, d_stif, t_stif, n_stif):
    """
    This function allows for generation of a stiffened box section
    This only works with Pint units aware data in SI format at the moment.
    """
    import copy
    import sectionproperties.pre.sections as sections
    from sectionproperties.analysis.cross_section import CrossSection

    # Create the main box sections
    top_flange = sections.RectangularSection(d=t_f, b=b, shift=[0, d - t_f])
    bot_flange = sections.RectangularSection(d=t_f, b=b, shift=[0, 0])
    left_web = sections.RectangularSection(d=d - 2 * t_f,
                                           b=t_w,
                                           shift=[0, t_f])
    right_web = sections.RectangularSection(d=d - 2 * t_f,
                                            b=t_w,
                                            shift=[b - t_w, t_f])

    if n_stif == 3:
        #Create top stiffeners
        top_stif1 = sections.RectangularSection(d=d_stif,
                                                b=t_stif,
                                                shift=[(b - t_stif) / 2,
                                                       d - t_f - d_stif])

        top_stif2 = copy.deepcopy(top_stif1)
        top_stif3 = copy.deepcopy(top_stif1)
        top_stif2.shift = [-b / 4, 0]
        top_stif3.shift = [b / 4, 0]
        top_stif2.shift_section()
        top_stif3.shift_section()

        #Create left stiffeners
        left_stif1 = sections.RectangularSection(d=t_stif,
                                                 b=d_stif,
                                                 shift=[t_w, (d - t_stif) / 2])

        left_stif2 = copy.deepcopy(left_stif1)
        left_stif3 = copy.deepcopy(left_stif1)
        left_stif2.shift = [0, -d / 4]
        left_stif3.shift = [0, d / 4]
        left_stif2.shift_section()
        left_stif3.shift_section()

        #Create right stiffeners
        right_stif1 = copy.deepcopy(left_stif1)
        right_stif2 = copy.deepcopy(left_stif2)
        right_stif3 = copy.deepcopy(left_stif3)
        right_stif1.shift = [b - 2 * t_w - d_stif, 0]
        right_stif2.shift = [b - 2 * t_w - d_stif, 0]
        right_stif3.shift = [b - 2 * t_w - d_stif, 0]
        right_stif1.shift_section()
        right_stif2.shift_section()
        right_stif3.shift_section()

        # create a list of the sections to be merged
        section_list = [
            top_flange, bot_flange, left_web, right_web, top_stif1, top_stif2,
            top_stif3, left_stif1, left_stif2, left_stif3, right_stif1,
            right_stif2, right_stif3
        ]

    elif n_stif == 2:
        #Create top stiffeners
        top_stif1 = sections.RectangularSection(d=d_stif,
                                                b=t_stif,
                                                shift=[(b - t_stif) / 3.0,
                                                       d - t_f - d_stif])

        top_stif2 = copy.deepcopy(top_stif1)
        top_stif2.shift = [b / 3, 0]
        top_stif2.shift_section()

        #Create left stiffeners
        left_stif1 = sections.RectangularSection(d=t_stif,
                                                 b=d_stif,
                                                 shift=[t_w, (d - t_stif) / 3])

        left_stif2 = copy.deepcopy(left_stif1)
        left_stif2.shift = [0, d / 3]
        left_stif2.shift_section()

        #Create right stiffeners
        right_stif1 = copy.deepcopy(left_stif1)
        right_stif2 = copy.deepcopy(left_stif2)
        right_stif1.shift = [b - 2 * t_w - d_stif, 0]
        right_stif2.shift = [b - 2 * t_w - d_stif, 0]
        right_stif1.shift_section()
        right_stif2.shift_section()

        # create a list of the sections to be merged
        section_list = [
            top_flange, bot_flange, left_web, right_web, top_stif1, top_stif2,
            left_stif1, left_stif2, right_stif1, right_stif2
        ]
    else:
        print("Number of stiffeners not supported")

    # merge the three sections into one geometry object
    geometry = sections.MergedSection(section_list)

    geometry.clean_geometry(verbose=False)  # clean the geometry
    geometry.add_hole([b / 2, d / 2])
    fig, ax = plt.subplots()
    ax.set_aspect('equal')
    geometry.plot_geometry(ax=ax)  # plot the geometry

    # create a mesh - use a mesh size of 12 for the RHS, 6 for stiffeners
    rhs_mesh = d / 6
    stif_mesh = t_stif

    if n_stif == 3:
        mesh = geometry.create_mesh(mesh_sizes=[
            rhs_mesh, rhs_mesh, rhs_mesh, rhs_mesh, stif_mesh, stif_mesh,
            stif_mesh, stif_mesh, stif_mesh, stif_mesh, stif_mesh, stif_mesh,
            stif_mesh
        ])
    elif n_stif == 2:
        mesh = geometry.create_mesh(mesh_sizes=[
            rhs_mesh, rhs_mesh, rhs_mesh, rhs_mesh, stif_mesh, stif_mesh,
            stif_mesh, stif_mesh, stif_mesh, stif_mesh
        ])
    else:
        print("Number of stiffeners not supported")

    section = CrossSection(geometry, mesh)  # create a CrossSection object

    return section, fig, ax
Exemplo n.º 15
0
def process_geometry(geometry, mesh_sizes, loadcases):
    # update this to receive the geometry, mesh info, material and loads

    # generate a finite element mesh
    mesh = geometry.create_mesh(mesh_sizes=mesh_sizes)

    # generate material - can be overwritten if needed --all in N and cm

    # create a CrossSection object for analysis
    section = CrossSection(geometry, mesh)

    # calculate various cross-section properties
    section.calculate_geometric_properties()
    section.calculate_warping_properties()
    section.calculate_plastic_properties()

    # Area
    area = section.get_area()
    sheararea = section.get_As()
    asx = sheararea[0]
    asy = sheararea[1]

    # Second Moment of Area about centroid
    (ixx, iyy, ixy) = section.get_ic()

    # Centroid
    (xg, yg) = section.get_c()

    # Radii of Gyration
    (rxx, ryy) = section.get_rc()

    # Principal bending axis angle
    phi = section.get_phi()
    # St. Venant torsion constant
    ipp = section.get_j()
    # Warping Constant
    cw = section.get_gamma()

    # Elastic Section Moduli
    (welx_top, welx_bottom, wely_top, wely_bottom) = section.get_z()

    # Plastic Section Moduli
    (wplx, wply) = section.get_s()

    # plot centroid to image
    section.plot_centroids(pause=False)
    buf = io.BytesIO()
    plt.savefig(buf, format='png', bbox_inches='tight')
    buf.seek(0)
    plot_centroid = base64.b64encode(buf.getvalue()).decode()
    plt.close()

    # calculate torsion resistance from stress and torque
    #from the below can also return torsional stress if wanted
    stress_post = section.calculate_stress(Mzz=10)
    unit_mzz_zxy = []
    maxstress = []
    for group in stress_post.material_groups:
        maxstress.append(max(group.stress_result.sig_zxy_mzz))
        unit_mzz_zxy.append(group.stress_result.sig_zxy_mzz.tolist())
    #there should be only one maxstress value therefore:
    wt = 10 / maxstress[0]

    #plot this image
    stress_post.plot_stress_mzz_zxy(pause=False)
    buf = io.BytesIO()
    plt.savefig(buf, format='png', bbox_inches='tight')
    buf.seek(0)
    plot_unittorsionstress = base64.b64encode(buf.getvalue()).decode()
    plt.close()

    #foreach load case submitted calculate vm stress state and create image

    vmStressImages = {}
    vmStressStates = {}
    for loadcase in loadcases:
        lc_name = loadcase[0]
        s_n = loadcase[1]
        s_vx = loadcase[2]
        s_vy = loadcase[3]
        s_mxx = loadcase[4]
        s_myy = loadcase[5]
        s_mzz = loadcase[6]
        stress_post = section.calculate_stress(N=s_n,
                                               Vx=s_vx,
                                               Vy=s_vy,
                                               Mxx=s_mxx,
                                               Myy=s_myy,
                                               Mzz=s_mzz)
        stress_state = []
        for group in stress_post.material_groups:
            stress_state.append(group.stress_result.sig_vm.tolist())
        vmStressStates['lc_' + str(lc_name) + '_vm_stress'] = stress_state
        #plot this image
        stress_post.plot_stress_vm(pause=False)
        buf = io.BytesIO()
        plt.savefig(buf, format='png', bbox_inches='tight')
        buf.seek(0)
        vmStressImages['lc_' + str(lc_name) + '_vm_stress'] = base64.b64encode(
            buf.getvalue()).decode()
        plt.close()

    # create rhino mesh
    rmesh = rhino_mesh_from_meshpy(mesh)

    # return send_file(path, as_attachment=True)

    # get some of the calculated section properties
    return_data = {}
    return_data['properties'] = {
        'area': area,
        'Avx': asx,
        'Avy': asy,
        'xg': xg,
        'yg': yg,
        'rxx': rxx,
        'ryy': ryy,
        'phi': phi,
        'ixx': ixx,
        'iyy': iyy,
        'ipp': ipp,
        'cw': cw,
        'welx+': welx_top,
        'welx-': welx_bottom,
        'wely+': wely_top,
        'wely-': wely_bottom,
        'wplx': wplx,
        'wply': wply,
        'wt': wt,
    }
    return_data['geometry'] = {
        'mesh': rhino.CommonObject.Encode(rmesh),
    }
    return_data['images'] = {
        'centroids': plot_centroid,
        'unittorsion_vxy_stress': plot_unittorsionstress,
    }
    return_data['images'].update(vmStressImages)
    return_data['stress_results'] = {
        'unittorsion_vxy_stress': unit_mzz_zxy,
    }
    return_data['stress_results'].update(vmStressStates)

    return return_data
Exemplo n.º 16
0
def _analyze_common_structural_geometry(step, geometry, mesh_sizes, N, Vx, Vy,
                                        Mxx, Myy, Mzz):
    mesh = geometry.create_mesh(mesh_sizes=[mesh_sizes])
    section = CrossSection(geometry, mesh)
    finite_elements_number = len(section.mesh_elements)
    if finite_elements_number > MAX_FINITE_ELEMENTS_NUMBER:
        return False, None, None, None, None, None, None, None, None, None, None
    elif finite_elements_number < MAX_FINITE_ELEMENTS_NUMBER and step == 'checking':
        return True, None, None, None, None, None, None, None, None, None, None
    else:
        section.calculate_geometric_properties()
        section.calculate_warping_properties()
        loadcase = section.calculate_stress(N=N,
                                            Vx=Vx,
                                            Vy=Vy,
                                            Mxx=Mxx,
                                            Myy=Myy,
                                            Mzz=Mzz)
        nodes = section.mesh_nodes
        stresses = loadcase.get_stress()[0]
        area = section.get_area()
        ixx_c, iyy_c, ixy_c = section.get_ic()
        torsion_constant = section.get_j()
        warping_constant = section.get_gamma()
        elastic_centroid = section.get_c()
        centroidal_shear_center = section.get_sc()
        return True, nodes, stresses, area, ixx_c, iyy_c, ixy_c, torsion_constant, warping_constant, \
               elastic_centroid, centroidal_shear_center
Exemplo n.º 17
0
    def calculate(self, loadProfileFromDB):
        '''Se ejecuta el calculo de las propiedades de la seccion.

            Parameters
            ----------
                loadProfileFromDB: bool
                    indica si se debe intentar cargar el perfil desde la base de datos
            Referencia
            ----------
                rx, ry : radio de giro del miembro | sqrt(I/A)
                c_i : coordenada del centroide de la seccion
                sc_i : coordenada del centro de corte
                A : Area de la seccion
                Cw : Constante torsional de warping de la seccion
                J : Constante de torsion de St. Venant
                Si : modulo elastico
                j : mitad de la constante monociclica a compresion en eje -y- (beta22-)

        '''
        if loadProfileFromDB:
            try:
                self.load()
            except:
                loadProfileFromDB = False
                pass
        if not loadProfileFromDB:
            ## CALCULO PROPIEDADES A PARTIR DEL PAQUETE sectionproperties
            geometry = sections.CeeSection(d=self.H, b=self.B, l=self.D, t=self.t, r_out=self.r_out, n_r=8)
            # create mesh
            mesh = geometry.create_mesh(mesh_sizes=[self.t/4.0])
            # creo la seccion
            section = CrossSection(geometry, mesh)
            # calculo las propiedades
            section.calculate_geometric_properties()
            section.calculate_warping_properties()

            (self.c_x, self.c_y) = section.get_c() # centroides
            (self.sc_x, self.sc_y) = section.get_sc() # shear center
            self.Cw = section.get_gamma() # warping
            (self.rx, self.ry) = section.get_rc() # radios de giro
            self.J = section.get_j()    # St Venant
            self.A = section.get_area()
            self.Ae = section.get_area()
            (self.Ix, self.Iy, _) = section.get_ic()
            (self.Sx, _, _, _) = section.get_z()    # modulo elastico
            self.j = section.get_beta_p()[3]/2.0

            self.save(section)

            self.section = section
Exemplo n.º 18
0
import sectionproperties.pre.sections as sections
from sectionproperties.analysis.cross_section import CrossSection

# create a 150x100x6 RHS on its side
geometry = sections.Rhs(d=100, b=150, t=6, r_out=15, n_r=8)

# create a mesh with a maximum area of 2
mesh = geometry.create_mesh(mesh_sizes=[2])

# create a CrossSection object
section = CrossSection(geometry, mesh)

# perform a geometry and warping analysis
section.calculate_geometric_properties()
section.calculate_warping_properties()

# perform a stress analysis with Mx = 5 kN.m; Vx = 10 kN and Mzz = 3 kN.m
case1 = section.calculate_stress(Mxx=5e6, Vx=10e3, Mzz=3e6)

# perform a stress analysis with My = 15 kN.m; Vy = 30 kN and Mzz = 1.5 kN.m
case2 = section.calculate_stress(Myy=15e6, Vy=30e3, Mzz=1.5e6)

case1.plot_stress_m_zz(pause=False)  # plot the bending stress for case1
case1.plot_vector_mzz_zxy(pause=False)  # plot the torsion vectors for case1
case2.plot_stress_v_zxy(pause=False)  # plot the shear stress for case1
case1.plot_stress_vm(pause=False)  # plot the von mises stress for case1
case2.plot_stress_vm()  # plot the von mises stress for case2
Exemplo n.º 19
0
    def calculate(self, loadProfileFromDB):
        '''Se ejecuta el calculo de las propiedades de la seccion.

        Referencia
        ----------
            rx, ry : radio de giro de la seccion | sqrt(I/A)
            ri : radio de giro en -y- de un solo perfil c
            c_x, c_y : coordenada del centroide de la seccion
            sc_x, sc_y : coordenada del centro de corte
            A : Area de la seccion
            Cw : Constante torsional de warping de la seccion
            J : Constante de torsion de St. Venant
            Si : modulo elastico
            j : mitad de la constante monociclica a compresion en eje -y- (beta22-)

        '''
        if loadProfileFromDB:
            try:
                self.load()
            except:
                loadProfileFromDB = False
                pass
        if not loadProfileFromDB:
            c0 = c_profile(H= self.H, B= self. B, t= self.t, r_out= self.r_out)
            c0.calculate(loadProfileFromDB)

            c1 = sections.CeeSection(d=self.H, b=self.B+self.r_out, l=self.r_out, t=self.t, r_out=self.r_out, n_r=8)
            c2 = deepcopy(c1)
        
            # corto los labios y el radio c1
            p1 = c1.add_point([self.B, 0])
            p2 = c1.add_point([self.B, self.t])
            p3 = c1.add_point([self.B, self.H])
            p4 = c1.add_point([self.B, self.H-self.t])

            c1.add_facet([p1, p2])
            c1.add_facet([p3, p4])
            c1.add_hole([self.B+self.r_out/10, self.t/2])  # add hole
            c1.add_hole([self.B+self.r_out/10, self.H-self.t/2])  # add hole
            c1.clean_geometry()  # clean the geometry

            c2 = deepcopy(c1)
            c2.mirror_section(axis= 'y', mirror_point=[0, 0])

            if self.s:
                c1.shift = [self.s/2, 0]
                c1.shift_section()

                c2.shift = [-self.s/2, 0]
                c2.shift_section()
            # soldadura en los extremos del alma
            if self.wld:
                h = self.wld*self.r_out # weld length
                a = self.wld*self.r_out*2 + self.s # base de la soldadura
                weld1 = sections.CustomSection(
                    points=[[a/2,0], [-a/2, 0], [0, h]],
                    facets=[[0,1], [1,2], [2,0]],
                    holes=[],
                    control_points=[[h / 3, h / 3]]
                )
                weld2 = deepcopy(weld1)

                weld2.mirror_section(axis= 'x', mirror_point=[0, 0])
                weld2.shift = [0, self.H]
                weld2.shift_section()

                geometry = sections.MergedSection([c1, c2, weld1, weld2])
                geometry.clean_geometry(verbose= False)

                if self.s:    
                    geometry.add_hole([0, self.H/2])
                mesh = geometry.create_mesh(mesh_sizes=[self.mesh_size, self.mesh_size, self.mesh_size, self.mesh_size])
            else:
                geometry = sections.MergedSection([c1, c2])
                geometry.clean_geometry()
                mesh = geometry.create_mesh(mesh_sizes=[self.mesh_size, self.mesh_size])
            
            section = CrossSection(geometry, mesh)

            #mesh_c1 = c1.create_mesh(mesh_sizes=[self.mesh_size])
            #section_c1 = CrossSection(c1, mesh_c1)

            #section_c1.calculate_geometric_properties()
            #section_c1.calculate_warping_properties()
            
            section.calculate_geometric_properties()
            section.calculate_warping_properties()

            (self.c_x, self.c_y) = section.get_c() # centroides
            (self.sc_x, self.sc_y) = section.get_sc() # shear center
            self.Cw = section.get_gamma() # warping
            (self.rx, self.ry) = section.get_rc() # radios de giro
            self.J = section.get_j()
            self.A = section.get_area()
            self.Ae = self.A
            self.ri = c0.ry # radios de giro y de c1
            (self.Ix, self.Iy, _) = section.get_ic()
            (self.Sx, _, _, _) = section.get_z()    # modulo elastico
            self.j = section.get_beta_p()[3]/2.0

            self.save(section)

            self.section = section
Exemplo n.º 20
0
class Beam(Component):
    '''Beam is a wrapper for emergent useful properties of the structure'''
    structure = attr.ib()  #parent structure, will be in its _beams
    name = attr.ib()
    material = attr.ib(validator=attr.validators.instance_of(SolidMaterial))
    section = attr.ib(validator=attr.validators.instance_of((
        sectionproperties.pre.sections.Geometry, ottgeo.Profile2D,
        type(None))))

    mesh_size = attr.ib(default=3)

    in_Iy = attr.ib(default=None,
                    validator=attr.validators.instance_of(
                        (int, float, nonetype)))
    in_Ix = attr.ib(default=None,
                    validator=attr.validators.instance_of(
                        (int, float, nonetype)))
    in_J = attr.ib(default=None,
                   validator=attr.validators.instance_of(
                       (int, float, nonetype)))
    in_A = attr.ib(default=None,
                   validator=attr.validators.instance_of(
                       (int, float, nonetype)))

    _L = None
    _section_properties = None
    _ITensor = None

    min_stress_xy = None  #set to true or false

    def __on_init__(self):
        self.info('initalizing...')
        self._skip_attr = ['mesh_size', 'in_Iy', 'in_Ix', 'in_J', 'in_A']

        self.update_section(self.section)

    def update_section(self, section):
        self.section = section

        self.debug(f'determining {section} properties...')
        if isinstance(self.section, sectionproperties.pre.sections.Geometry):
            self.debug(f'determining mesh {section} properties...')
            mesh = self.section.create_mesh([self.mesh_size])
            self._section_properties = CrossSection(self.section,
                                                    mesh)  #no material here
            self._section_properties.calculate_geometric_properties()
            self._section_properties.calculate_warping_properties()

        elif isinstance(self.section, ottgeo.Profile2D):
            self.debug(f'determining profile {section} properties...')
            self._section_properties = self.section

        else:
            self.debug(f'checking input values')
            assert all([
                val is not None
                for val in (self.in_Iy, self.in_Ix, self.in_J, self.in_A)
            ])

    def apply_pt_load(self, gFx, gFy, gFz, x, case='Case 1'):
        '''add a force in a global orientation'''

        Fvec = numpy.array([gFx, gFy, gFz])

        self.debug(f'adding pt load {Fvec}')

        Floc = self.ReverseRotationMatrix.dot(Fvec)
        Flx = Floc[0]
        Fly = Floc[1]
        Flz = Floc[2]

        for Fkey, Fval in [('Fx', Flx), ('Fy', Fly), ('Fz', Flz)]:
            if Fval:
                self.debug(f'adding {Fkey}={Fval}')
                self.structure.frame.AddMemberPtLoad(self.member.Name, Fkey,
                                                     Fval, x)
ub = sections.ISection(d=304, b=165, t_f=10.2, t_w=6.1, r=11.4, n_r=8)

# create timber panel on top of the UB
panel = sections.RectangularSection(d=50, b=600, shift=[-217.5, 304])

# merge the two sections into one geometry object
geometry = sections.MergedSection([ub, panel])
geometry.clean_geometry()  # clean the geometry
geometry.plot_geometry()  # plot the geometry

# create a mesh - use a mesh size of 5 for the UB, 20 for the panel
mesh = geometry.create_mesh(mesh_sizes=[5, 20])

# create a CrossSection object - take care to list the materials in the same order as entered into
# the MergedSection
section = CrossSection(geometry, mesh, materials=[steel, timber])
section.display_mesh_info()  # display the mesh information

# plot the mesh with coloured materials and a line transparency of 0.5
section.plot_mesh(materials=True, alpha=0.5)

# perform a geometric, warping and plastic analysis
section.calculate_geometric_properties(time_info=True)
section.calculate_warping_properties(time_info=True)
section.calculate_plastic_properties(time_info=True, verbose=True)

# perform a stress analysis with N = 100 kN, Mxx = 120 kN.m and Vy = 75 kN
stress_post = section.calculate_stress(N=-100e3,
                                       Mxx=-120e6,
                                       Vy=-75e3,
                                       time_info=True)
Exemplo n.º 22
0
class OneSec:
    """表示一个截面"""
    def __init__(self, pls):
        """
        单独截面
        :param pls: 多条 cad 多段线对象组成的列表,其中应有一根指示控制点的线
        """

        # 原始线和控制点
        self.pls_origin = []
        self.points = []
        for i in pls:
            if i.area == 0:
                self.points = i.id
            else:
                self.pls_origin.append(i)

        # 对线段进行排序,得到分离节点和完整节点
        self.areas = np.array([i.area for i in self.pls_origin])
        self.pls = np.array(self.pls_origin)[np.argsort(self.areas)][::-1]
        self.ids_sep = [i.id for i in self.pls]
        self.ids = [j.tolist() for i in self.ids_sep for j in i]

        # 获取节点连接方式
        self.faces = []
        id_num = 0
        for i in self.ids_sep:
            id_num_0 = id_num
            for j in i:
                connect = [
                    id_num, id_num_0
                ] if id_num + 1 == id_num_0 + len(i) else [id_num, id_num + 1]
                self.faces.append(connect)
                id_num += 1

        # 定义其他所需值
        self.geo = 0
        self.mesh = 0
        self.sec = 0
        self.prop = {}
        self.stress = 0
        self.corner = []
        self.ids_to_c = []

    def sec_cal(self, mesh=0.01, d=0.03):
        """
        对单个截面进行属性计算
        :param mesh: 截面划分单元尺寸
        :param d: 截取形心附近应力范围
        :return: 无
        """

        self.geo = sections.CustomSection(self.ids, self.faces,
                                          self.points[1:], [self.points[0]])
        self.mesh = self.geo.create_mesh(mesh_sizes=[mesh])
        self.sec = CrossSection(self.geo, self.mesh)
        self.sec.plot_mesh()
        self.sec.calculate_geometric_properties()
        self.sec.calculate_warping_properties()

        # 获取截面属性
        prop = self.sec.section_props
        self.prop['center'] = self.sec.get_c()
        self.ids_to_c = [i - self.prop['center'] for i in self.ids_sep]
        self.prop['area'] = prop.area
        self.prop['as'] = [prop.A_s22, prop.A_s11]
        self.prop['i'] = [prop.j, prop.ixx_c, prop.iyy_c]
        pts = np.array(self.ids)
        left = prop.cx - pts[:, 0].min()
        right = pts[:, 0].max() - prop.cx
        top = pts[:, 1].max() - prop.cy
        bot = prop.cy - pts[:, 1].min()
        self.prop['c'] = [right, left, top, bot]

        self.stress = self.sec.calculate_stress(Vx=1, Vy=1)
        stresses = self.stress.get_stress()
        dy = self.sec.get_c()[1] - self.sec.mesh_nodes[:, 1]
        dx = self.sec.get_c()[0] - self.sec.mesh_nodes[:, 0]
        qyb = stresses[0]['sig_zy_vy'][dx < d].max() * prop.ixx_c
        qzb = stresses[0]['sig_zx_vx'][dy < d].max() * prop.iyy_c
        self.prop['q'] = [qyb, qzb]
        self.prop['p'] = [
            self.pls[0].length,
            sum([i.length for i in self.pls[1:]])
        ]

        # 获取角点
        pt_all = self.ids_to_c[0]
        pt_1 = pt_all[(pt_all[:, 0] < 0) & (pt_all[:, 1] > 0)]
        pt_2 = pt_all[(pt_all[:, 0] > 0) & (pt_all[:, 1] > 0)]
        pt_3 = pt_all[(pt_all[:, 0] < 0) & (pt_all[:, 1] < 0)]
        pt_4 = pt_all[(pt_all[:, 0] > 0) & (pt_all[:, 1] < 0)]
        pt_1 = find_pt(pt_1, relation='max')
        pt_2 = find_pt(pt_2, relation='max')
        pt_3 = find_pt(pt_3, relation='max')
        pt_4 = find_pt(pt_4, relation='max')
        self.corner = [pt_1, pt_2, pt_4, pt_3]