Example #1
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
Example #2
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
Example #3
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
Example #4
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
Example #5
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
Example #6
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]