示例#1
0
def long_cantilever_500_members():
    Cantilever = FEModel3D()

    # Adding in 1001 nodes 1ft apart, building it out from left to right
    for i in range(501):
        Cantilever.AddNode(f"N{i + 1}", i, 0, 0)

    # Adding in 1000 members end to end, building it out from left to right
    # AISC W8x31
    # E = 29000 ksi, G = 11200 ksi, Iy = 37.1 in^4, Iz = 110 in^4, J = 0.536 in^4, A = 9.13 in^2
    for i in range(500):
        Cantilever.AddMember(Name=f"M{i + 1}",
                             iNode=f"N{i + 1}",
                             jNode=f"N{i + 2}",
                             E=29000,
                             G=11200,
                             Iy=37.1,
                             Iz=110,
                             J=0.536,
                             A=9.13)

    # Fixed end on left end
    Cantilever.DefineSupport("N1", True, True, True, True, True, True)

    return Cantilever
示例#2
0
 def test_unstable_supports(self):
     # This test checks the PyNite's ability to detect unstable support conditions
     # Units used in this test are inches, and kips
     MomentFrame = FEModel3D()
     # Add nodes (frame is 15 ft wide x 12 ft tall)
     MomentFrame.AddNode("N1", 0, 0, 0)
     MomentFrame.AddNode("N2", 0, 12 * 12, 0)
     MomentFrame.AddNode("N3", 15 * 12, 12 * 12, 0)
     MomentFrame.AddNode("N4", 15 * 12, 0 * 12, 0)
     # Add columns with the following properties:
     # E = 29000 ksi, G = 11400 ksi, Iy = 100 in^4, Iz = 150 in^4, J = 250 in^4, A = 10 in^2
     MomentFrame.AddMember("M1", "N1", "N2", 29000, 11400, 100, 150, 250,
                           10)
     MomentFrame.AddMember("M2", "N4", "N3", 29000, 11400, 100, 150, 250,
                           10)
     # Add a beam with the following properties:
     # E = 29000 ksi, G = 11400 ksi, Iy = 100 in^4, Iz = 250 in^4, J = 250 in^4, A = 15 in^2
     MomentFrame.AddMember("M3", "N2", "N3", 29000, 11400, 100, 250, 250,
                           15)
     # Provide unstable supports (unsupported in DY)
     MomentFrame.DefineSupport("N1", True, False, True, True, True, True)
     # Add a nodal lateral load of 50 kips at the left side of the frame
     MomentFrame.AddNodeLoad("N2", "FX", 50)
     # Analyze the frame - we should see an error message that the structure is unstable
     with self.assertRaises(Exception):
         MomentFrame.Analyze()
示例#3
0
    def test_member_torque_load(self):
        TorqueBeam = FEModel3D()
        # Add nodes (14 ft = 168 in apart)
        TorqueBeam.add_node('N1', 0, 0, 0)
        TorqueBeam.add_node('N2', 168, 0, 0)
        # Add a beam with the following properties:
        TorqueBeam.add_member('M1', 'N1', 'N2', 29000, 11400, 100, 150, 250,
                              20)
        # Provide fixed supports
        TorqueBeam.def_support('N1', False, True, True, True, True, True)
        TorqueBeam.def_support('N2', True, True, True, True, True, True)
        # Add a point load of 5 kip-ft and 10 kip-ft at 3ft and 11 ft along the beam respectively
        TorqueBeam.add_member_pt_load('M1', 'Mx', 5, 3 * 12)
        TorqueBeam.add_member_pt_load('M1', 'Mx', 10, 11 * 12)
        TorqueBeam.analyze(check_statics=True)
        # Support reactions (around local x axis) at each end
        left_Rxn = TorqueBeam.Nodes['N1'].RxnMX['Combo 1']
        # subTest context manager prints which portion fails, if any
        with self.subTest(left_Rxn=left_Rxn):
            self.assertAlmostEqual(left_Rxn, -6.07, 2)

        right_Rxn = TorqueBeam.Nodes['N2'].RxnMX['Combo 1']
        with self.subTest(right_Rxn=right_Rxn):
            self.assertAlmostEqual(right_Rxn, -8.93, 2)

        # Max/min torques on the beam
        max_torque = TorqueBeam.Members['M1'].max_torque()
        with self.subTest(max_torque=max_torque):
            self.assertAlmostEqual(max_torque, 8.93, 2)

        min_torque = TorqueBeam.Members['M1'].min_torque()
        with self.subTest(min_torque=min_torque):
            self.assertAlmostEqual(min_torque, -6.07, 2)
示例#4
0
 def test_XZ_ptload(self):
     # A simply supported beam with a point load.
     # Units used in this example are inches, and kips
     SimpleBeam = FEModel3D()
     # Add nodes (14 ft = 168 in apart)
     SimpleBeam.AddNode("N1", 0, 0, 0)
     SimpleBeam.AddNode("N2", 0, 0, 168)
     # Add a beam with the following properties:
     A = 20
     E = 29000
     G = 11400
     Iy = 100
     Iz = 150
     J = 250
     SimpleBeam.AddMember("M1", "N1", "N2", E, G, Iy, Iz, J, A)
     # Provide simple supports
     SimpleBeam.DefineSupport("N1", True, True, True, False, False, True)
     SimpleBeam.DefineSupport("N2", True, True, True, False, False, False)
     # Add a point load of 5 kips at the midspan of the beam
     SimpleBeam.AddMemberPtLoad("M1", "Fy", 5, 7 * 12)
     # Analyze the beam
     SimpleBeam.Analyze(False)
     # Print reactions at each end of the beam
     correct_reactions = [('N1', -2.5),
                          ('N2', -2.5)]
     for node_name, rxn in correct_reactions:
         with self.subTest(node=node_name):
             calculated_reaction = SimpleBeam.GetNode(node_name).RxnFY['Combo 1']
             # Two decimal place accuracy requires +/-0.5% accuracy
             # one decimal place requires +/-5%
             self.assertAlmostEqual(calculated_reaction/rxn, 1.0, 2)
             
示例#5
0
    def test_hydrostatic_plate(self):

        # Establish problem parameters
        t = 1  # ft
        E = 57000 * math.sqrt(4500) * 12**2  # psf
        nu = 1 / 6
        mesh_size = 1  # ft
        a = 10  # ft
        b = 15  # ft

        # Generate the mesh of plates
        plate_mesh = RectangleMesh(mesh_size,
                                   a,
                                   b,
                                   t,
                                   E,
                                   nu,
                                   kx_mod=1,
                                   ky_mod=1,
                                   element_type='Rect')
        plate_mesh.generate()

        # Create the model and add the plates
        plate_model = FEModel3D()
        plate_model.add_mesh(plate_mesh)

        # Add supports to the sides and base of the wall
        for node in plate_model.Nodes.values():
            if node.X == 0 or node.X == a or node.Y == 0:
                plate_model.def_support(node.name, True, True, True, True,
                                        True, True)

        # Add hydrostatic loads to the elements
        for element in plate_model.Plates.values():
            Yavg = (element.i_node.Y + element.j_node.Y + element.m_node.Y +
                    element.n_node.Y) / 4
            p = 62.4 * (b - Yavg)
            plate_model.add_plate_surface_pressure(element.name, p,
                                                   'Hydrostatic')

        # Add a load combination to the model
        plate_model.add_load_combo('F', {'Hydrostatic': 1.0})

        # Analyze the model
        plate_model.analyze()

        # Get the maximum deflection in the model at the top of the wall
        DZ_calcd = max([
            node.DZ['F'] for node in plate_model.Nodes.values() if node.Y == b
        ])

        # Find the maximum deflection at the top of the wall from Timoshenko's Table 45
        q = 62.4 * b
        D = E * t**3 / (12 * (1 - nu**2))
        DZ_expected = 0.00042 * q * a**4 / D

        # Check that the PyNite calculated values are within 15% of the Timoshenko calculated
        # values.
        self.assertLess(abs(DZ_calcd / DZ_expected - 1), 0.15,
                        'Failed Timoshenko rectangle hydrostatic test.')
示例#6
0
 def test_XY_member_ptload(self):
     frame = FEModel3D()
     # Add nodes
     frame.AddNode('N1', 0, 0, 0)        # ft
     frame.AddNode('N2', 0, 7.667, 0)    # ft
     frame.AddNode('N3', 7.75, 7.667, 0) # ft
     frame.AddNode('N4', 7.75, 0, 0)     # ft
     # Add supports
     frame.DefineSupport('N1', True, True, True, True, True, False)
     frame.DefineSupport('N4', True, True, True, True, True, False)
     # Define material and section properties for a W8x24
     E = 29000*12**2     # ksf
     G = 1111200*12**2   # ksf
     Iy = 18.3/12**4     # ft^4
     Iz = 82.7/12**4     # ft^4
     J = 0.346/12**4     # ft^4
     A = 5.26/12**2      # in^2
     # Define members
     frame.AddMember('M1', 'N1', 'N2', E, G, Iy, Iz, J, A)
     frame.AddMember('M2', 'N2', 'N3', E, G, Iy, Iz, J, A)
     frame.AddMember('M3', 'N4', 'N3', E, G, Iy, Iz, J, A)
     # Add loads to the frame
     frame.AddMemberPtLoad('M2', 'Fy', -5, 7.75/2)       # 5 kips @ midspan
     frame.AddMemberDistLoad('M2', 'Fy', -0.024, -0.024) # W8x24 self-weight
     # Analyze the frame
     frame.Analyze()
     calculated_RZ = frame.GetNode('N1').RZ['Combo 1']
     # Update the expected value to an appropriate precision
     expected_RZ = 0.00022794540510395617
     self.assertAlmostEqual(calculated_RZ/expected_RZ, 1.0, 2)
示例#7
0
def pin_fixed_beam(length):
    PinFixBeam = FEModel3D()

    # Add nodes (14 ft = 168 in apart)
    PinFixBeam.AddNode("N1", 0, 0, 0)
    PinFixBeam.AddNode("N2", length, 0, 0)

    # Add a beam with the following properties:
    # E = 29000 ksi, G = 11200 ksi, Iy = 100 in^4, Iz = 150 in^4, J = 250 in^4, A = 20 in^2
    PinFixBeam.AddMember("M1",
                         "N1",
                         "N2",
                         E=29000,
                         G=11200,
                         Iy=100,
                         Iz=150,
                         J=250,
                         A=20)

    # Supports: Pin, Fixed
    PinFixBeam.DefineSupport("N1",
                             SupportDX=True,
                             SupportDY=True,
                             SupportDZ=True,
                             SupportRX=True)
    PinFixBeam.DefineSupport("N2",
                             SupportDX=True,
                             SupportDY=True,
                             SupportDZ=True,
                             SupportRX=True,
                             SupportRZ=True)

    return PinFixBeam
示例#8
0
 def test_axial_distributed_load(self):
     # Units N e m
     Beam = FEModel3D()
     L = 5  # m
     # Nodes
     Beam.add_node("N1", 0, 0, 0)
     Beam.add_node("N2", L, 0, 0)
     # Beams (30x50 cm)
     E = 2.1e11  # N/m^2
     G = 1
     Iy = 0.001125  # m^4
     Iz = 0.003125  # m^4
     J = 1
     A = 0.15  # m^2
     Beam.add_member("M1", "N1", "N2", E, G, Iy, Iz, J, A)
     # Supports
     Beam.def_support("N1", True, True, True, True, True, True)
     Beam.def_support("N2", True, True, True, False, True, True)
     # Load
     Beam.add_member_dist_load("M1", "Fx", 10, 10, 0, 5)
     # Analyze
     Beam.analyze()
     # Member fixed end reaction vector
     # print('M1 Displacement Vector: ', Beam.Members['M1'].d())
     # print('M1 Fixed End Reaction Vector: ', Beam.Members['M1'].fer())
     # Reactions
     for node_name in ('N1', 'N2'):
         with self.subTest(node=node_name):
             rxn = Beam.Nodes[node_name].RxnFX['Combo 1']
             self.assertAlmostEqual(rxn / -25.0, 1.0, 2)
示例#9
0
    def __init__(self,
                 width,
                 height,
                 thickness,
                 E=3824,
                 nu=0.3,
                 mesh_size=1,
                 bot_support='Pinned',
                 top_support='Pinned',
                 left_support='Free',
                 right_support='Free'):

        self.width = width
        self.height = height
        self.thickness = thickness
        self.mesh_size = mesh_size

        self.E = E
        self.nu = nu

        self.fem = FEModel3D()  # A finite element model for the wall

        self.loads = []  # A list of surface loads applied to the wall panel
        self.nodes = []  # A list of nodes that make up the wall panel
        self.plates = []  # A list of plates that make up the wall panel

        self.bot_support = bot_support
        self.top_support = top_support
        self.left_support = left_support
        self.right_support = right_support

        self.__analyzed = False
示例#10
0
    def test_support_settlement(self):

        # Create a new beam
        beam = FEModel3D()

        # Add nodes
        beam.AddNode('A', 0, 0, 0)
        beam.AddNode('B', 20 * 12, 0, 0)
        beam.AddNode('C', 40 * 12, 0, 0)
        beam.AddNode('D', 60 * 12, 0, 0)

        # Add members
        A = 20
        E = 29000
        G = 11400
        Iy = 1000
        Iz = 7800
        J = 8800
        beam.AddMember('AB', 'A', 'B', E, G, Iy, Iz, J, A)
        beam.AddMember('BC', 'B', 'C', E, G, Iy, Iz, J, A)
        beam.AddMember('CD', 'C', 'D', E, G, Iy, Iz, J, A)

        # Provide supports
        beam.DefineSupport('A', True, True, True, True, False, False)
        beam.DefineSupport('B', False, True, True, False, False, False)
        beam.DefineSupport('C', False, True, True, False, False, False)
        beam.DefineSupport('D', False, True, True, False, False, False)

        # Add a uniform load to the beam
        beam.AddMemberDistLoad('AB', 'Fy', -2 / 12, -2 / 12)
        beam.AddMemberDistLoad('BC', 'Fy', -2 / 12, -2 / 12)
        beam.AddMemberDistLoad('CD', 'Fy', -2 / 12, -2 / 12)

        # Add support settlements
        beam.AddNodeDisplacement('B', 'DY', -5 / 8)
        beam.AddNodeDisplacement('C', 'DY', -1.5)
        beam.AddNodeDisplacement('D', 'DY', -0.75)

        # Analyze the beam
        beam.Analyze()

        # Below are the textbook reactions given in the back of the textbook
        textbook_rxns = [('A', -1.098), ('B', 122.373), ('C', -61.451),
                         ('D', 60.176)]

        # Check each textbook value against the PyNite calculated value
        for name, text_rxn in textbook_rxns:

            # The `subTest` context manager prints which, if any, of the nodes fail the test
            with self.subTest(node=name):

                # Get the reaction at the node
                PyNite_rxn = beam.Nodes[name].RxnFY['Combo 1']

                # There are some known rounding errors in the "textbook values" listed above. These
                # rounding errors cause up to a 7.6% difference from the theoretical solution.
                # Check that the PyNite reactions are within 7.6% of the textbook values
                self.assertLess(abs(PyNite_rxn / text_rxn - 1), 0.076)
示例#11
0
    def analyse(self):
        self.frame = FEModel3D()

        # Add nodes
        for i in range(0, self.Nt):
            nname = self.__create_name('N', i)
            self.frame.AddNode(nname, self.node[i,0], self.node[i,1], self.node[i,2])
            self.frame.AddNodeLoad(nname, 'FX', self.node[i,3])
            self.frame.AddNodeLoad(nname, 'FY', self.node[i,4])
            self.frame.AddNodeLoad(nname, 'FZ', self.node[i,5])

        # Fix outer ring of nodes
        for n in range(1, self.Nn + 1):
            r, n, index = self.RNI(self.Nr, n)
            nname = self.__create_name('N', index)
            self.frame.DefineSupport(nname, True, True, True, True, True, True)

        for e in self.edge:
            r0, n0, i0 = e['node0']
            r1, n1, i1 = e['node1']

            mname  = e['mname']
            nname0 = self.__create_name('N', i0)
            nname1 = self.__create_name('N', i1)

            group = self.group[e['gname']]
            sectype  = group['sec_type']
            secindex = group['sec_index']
            material = group['material']

            area = sectype.get(secindex, 'area')
            Iyy  = sectype.get(secindex, 'Iyy')
            Izz  = sectype.get(secindex, 'Izz')
            J    = sectype.get(secindex, 'J')

            E = material['Young']
            G = material['Shear']

            self.frame.AddMember(mname, nname0, nname1, E, G, Iyy, Izz, J, area, self.dome_origin)

        if self.verbose:
            print('Setup complete. Analysing...')

        self.frame.Analyze()

        if self.verbose:
            print('Done.')

        max_deflection = 0
        for i in range(0, self.Nt):
            Ni = self.frame.GetNode(self.__create_name('N', i))
            deflection = np.linalg.norm(np.asarray([Ni.DX, Ni.DY, Ni.DZ]))
            if max_deflection < deflection:
                max_deflection = deflection

        return self.dome_mass, self.__maximum_bending_stress(), max_deflection
示例#12
0
    def test_hydrostatic_quad(self):

        # Establish problem parameters
        t = 1  # ft
        E = 57000 * math.sqrt(4500) * 12**2  # psf
        nu = 1 / 6
        mesh_size = 1  # ft
        a = 10  # ft
        b = 15  # ft

        # Generate the mesh of plates
        plate_mesh = RectangleMesh(t,
                                   E,
                                   nu,
                                   mesh_size,
                                   a,
                                   b,
                                   element_type='Quad')

        # Create the model and add the plates
        plate_model = FEModel3D()
        plate_model.AddMesh(plate_mesh)

        # Add supports to the sides and base of the wall
        for node in plate_model.Nodes.values():
            if node.X == 0 or node.X == a or node.Y == 0:
                plate_model.DefineSupport(node.Name, True, True, True, True,
                                          True, True)

        # Add hydrostatic loads to the elements
        for element in plate_model.Quads.values():
            Yavg = (element.iNode.Y + element.jNode.Y + element.mNode.Y +
                    element.nNode.Y) / 4
            p = 62.4 * (b - Yavg)
            plate_model.AddQuadSurfacePressure(element.Name, p, 'Hydrostatic')

        # Add a load combination to the model
        plate_model.AddLoadCombo('F', {'Hydrostatic': 1.0})

        # Analyze the model
        plate_model.Analyze()

        # Find the maximum deflection in the model
        dz_calcd = max([
            node.DZ['F'] for node in plate_model.Nodes.values() if node.Y == b
        ])
        q = 62.4 * b
        D = E * t**3 / (12 * (1 - nu**2))
        dz_expected = 0.00042 * q * a**4 / D

        # Check that the PyNite calculated values are within 15% of the Timoshenko calculated
        # values.
        self.assertLess(abs(dz_calcd / dz_expected - 1), 0.15,
                        'Failed Timoshenko quadrilateral hydrostatic test.')
示例#13
0
    def test_plate_displacement(self):
        """
        # A First Course in the Finite Element Method, 4th Edition
        # Daryl L. Logan
        # Example 12.1
        # Units for this model are pounds and inches
        """

        plModel = FEModel3D()

        plModel.add_node('N1', 0, 0, 0)
        plModel.add_node('N2', 10, 0, 0)
        plModel.add_node('N3', 20, 0, 0)
        plModel.add_node('N4', 0, 10, 0)
        plModel.add_node('N5', 10, 10, 0)
        plModel.add_node('N6', 20, 10, 0)
        plModel.add_node('N7', 0, 20, 0)
        plModel.add_node('N8', 10, 20, 0)
        plModel.add_node('N9', 20, 20, 0)

        plModel.add_plate('P1', 'N1', 'N2', 'N5', 'N4', 0.1, 30000000, 0.3)
        plModel.add_plate('P2', 'N2', 'N3', 'N6', 'N5', 0.1, 30000000, 0.3)
        plModel.add_plate('P3', 'N4', 'N5', 'N8', 'N7', 0.1, 30000000, 0.3)
        plModel.add_plate('P4', 'N5', 'N6', 'N9', 'N8', 0.1, 30000000, 0.3)

        plModel.add_node_load('N5', 'FZ', -100)

        plModel.def_support('N1', True, True, True, True, True, True)
        plModel.def_support('N2', True, True, True, True, True, True)
        plModel.def_support('N3', True, True, True, True, True, True)
        plModel.def_support('N4', True, True, True, True, True, True)
        plModel.def_support('N6', True, True, True, True, True, True)
        plModel.def_support('N7', True, True, True, True, True, True)
        plModel.def_support('N8', True, True, True, True, True, True)
        plModel.def_support('N9', True, True, True, True, True, True)

        plModel.def_support('N5', True, True, False, False, False, True)

        # Check to see if the stiffness matrix for each plate is symmetric
        # print(allclose(plModel.Plates[0].K(), plModel.Plates[0].K().T))
        # print(allclose(plModel.Plates[1].K(), plModel.Plates[1].K().T))
        # print(allclose(plModel.Plates[2].K(), plModel.Plates[2].K().T))
        # print(allclose(plModel.Plates[3].K(), plModel.Plates[3].K().T))

        # Check to see if the global stiffness matrix is symmetric
        # print(allclose(plModel.K(Renumber=True), plModel.K(Renumber=False).T))

        plModel.analyze(check_statics=True, sparse=False)
        # Test: displacement of N5 in Z direction
        calculated_displacement = plModel.Nodes['N5'].DZ['Combo 1']
        expected_displacement = -0.0861742424242424
        self.assertAlmostEqual(calculated_displacement / expected_displacement,
                               1.0, 2)
    def test_AISC_Benckmark(self):
        # Create the cantilever model
        cantilever = FEModel3D()

        # Define the column and its properties
        L = 20  # ft
        H = 5  # kips lateral load
        P = 100  # kips axial load
        G = 11200 * 12**2  # shear modulus (ksf)
        E = 29000 * 12**2  # modulus of elasticity (ksf)
        I = 100 / 12**4  # moment of inertia (ft^4)

        # Break the column into several segments in order to capture P-little-delta effects
        num_segs = 5
        num_nodes = num_segs + 1
        for i in range(num_nodes):
            # Add nodes
            cantilever.add_node(str(i + 1), 0, i * L / (num_segs), 0)

        for i in range(num_segs):
            # Add members between nodes
            cantilever.add_member(str(i + 1), str(i + 1), str(i + 2), E, G, I,
                                  I, 200 / 12**4, 10 / 12**2)

        # Add a fixed support at the base of the column
        cantilever.def_support('1', True, True, True, True, True, True)

        # Add a -10 kip axial load to the top of the column
        cantilever.add_node_load(str(num_nodes), 'FY', -P)

        # Add a 5 kip lateral load to the top of the column
        cantilever.add_node_load(str(num_nodes), 'FX', H)

        # Perform 2nd order analysis
        cantilever.analyze_PDelta()

        # The moment at the base of the column
        calculated_moment = cantilever.Nodes['1'].RxnMZ['Combo 1']

        # the deflection at the top of the column
        calculated_displacement = cantilever.Nodes[str(
            num_nodes)].DX['Combo 1'] * 12

        # Calculate the AISC benchmark problem solution:
        alpha = (P * L**2 / (E * I))**0.5
        Mmax = H * L * (math.tan(alpha) / alpha)
        ymax = H * L**3 / (3 * E * I) * (3 *
                                         (math.tan(alpha) - alpha) / alpha**3)

        # Compare the calculation results
        self.assertAlmostEqual(calculated_moment / Mmax, 1.0, 1)
        self.assertAlmostEqual(calculated_displacement / (ymax * 12), 1.0, 1)
示例#15
0
    def __init__(self, file, default_behavior='bonded'):
        self.igs = IGES_Object(file)
        self.model = FEModel3D()
        self.highest = [-np.inf, -np.inf, -np.inf]
        self.lowest = [+np.inf, +np.inf, +np.inf]

        # "Big picture" members and nodes... the ones that really matter.
        self.members = []

        for i, entity in enumerate(self.igs.toplevel_entities):
            self.loadEntity(str(i + 1), entity)

        print("Bounding box: ", self.lowest, self.highest)
示例#16
0
    def test_beam_on_elastic_foundation(self):
        '''        
        Matrix Structural Analysis, 2nd Edition
        William McGuire, Richard H. Gallagher, Ronald D. Ziemian
        Example 4.15
        Units for this model are kips and inches
        '''

        # Create a new model
        boef = FEModel3D()

        # Define nodes
        for i in range(17):

            # Add nodes spaced at 15"
            boef.add_node('N' + str(i + 1), i*15, 0, 0)

            # Add supports to the nodes
            if i == 0 or i == 16:
                boef.def_support('N' + str(i + 1), True, True, True, True, False, False)
            else:
                boef.def_support_spring('N' + str(i + 1), 'DY', 22.5, '-')

        # Define member material properties
        E = 29000   # ksi
        G = 11200   # ksi
        A = 10.3    # in^2
        Iz = 128.5  # in^4 (strong axis)
        Iy = 42.6   # in^4 (weak axis)
        J = 0.769   # in^4

        # Define members
        for i in range(16):

            # Add the members
            boef.add_member('M' + str(i + 1), 'N' + str(i + 1), 'N' + str(i + 2), E, G, Iy, Iz, J, A)
        
        # Add a point load at midspan
        boef.add_node_load('N9', 'FY', -40)

        # Analyze the model
        boef.analyze(sparse=False)

        print(boef.Members['M8'].min_moment('Mz'))
        print(boef.Members['M8'].max_moment('Mz'))

        # Check that results are within 5% of the expected answer
        self.assertLess(boef.Nodes['N9'].DY['Combo 1']/(-0.238) - 1, 0.05, 'Failed beam on elastic foundation test.')
        self.assertLess(-boef.Members['M8'].min_moment('Mz')/547 - 1, 0.05, 'Failed beam on elastic foundation test.')
示例#17
0
 def test_XY_gravity_load(self):
     # A First Course in the Finite Element Method, 4th Edition
     # Daryl L. Logan
     # Problem 5.30
     # Units for this model are kips and inches
     frame = FEModel3D()
     # Define the nodes
     frame.AddNode('N1', 0, 0, 0)
     frame.AddNode('N2', 0, 30*12, 0)
     frame.AddNode('N3', 15*12, 40*12, 0)
     frame.AddNode('N4', 35*12, 40*12, 0)
     frame.AddNode('N5', 50*12, 30*12, 0)
     frame.AddNode('N6', 50*12, 0, 0)
     # Define the supports
     frame.DefineSupport('N1', True, True, True, True, True, True)
     frame.DefineSupport('N6', True, True, True, True, True, True)
     # Create members (all members will have the same properties in this example)
     J = 250
     Iy = 250
     Iz = 200
     E = 30000
     G = 250
     A = 12
     frame.AddMember('M1', 'N1', 'N2', E, G, Iy, Iz, J, A)
     frame.AddMember('M2', 'N2', 'N3', E, G, Iy, Iz, J, A)
     frame.AddMember('M3', 'N3', 'N4', E, G, Iy, Iz, J, A)
     frame.AddMember('M4', 'N4', 'N5', E, G, Iy, Iz, J, A)
     frame.AddMember('M5', 'N5', 'N6', E, G, Iy, Iz, J, A)
     # Add nodal loads
     frame.AddNodeLoad('N3', 'FY', -30)
     frame.AddNodeLoad('N4', 'FY', -30)
     # Analyze the model
     frame.Analyze()
     # subTest context manager prints which portion fails, if any
     correct_values = [('N1', {'RxnFX': 11.6877,
                               'RxnFY': 30,
                               'RxnMZ': -1810.0745}),
                       ('N6', {'RxnFX': -11.6877,
                               'RxnFY': 30,
                               'RxnMZ': 1810.0745})]
     for name, values in correct_values:
         with self.subTest(node=name):
             node = frame.GetNode(name)
             # Two decimal place accuracy requires +/-0.5% accuracy
             # one decimal place requires +/-5%
             self.assertAlmostEqual(node.RxnFX['Combo 1']/values['RxnFX'], 1.0, 2)
             self.assertAlmostEqual(node.RxnFY['Combo 1']/values['RxnFY'], 1.0, 2)
             self.assertAlmostEqual(node.RxnMZ['Combo 1']/values['RxnMZ'], 1.0, 2)
示例#18
0
def two_span_beam(length):
    TwoSpanBeam = FEModel3D()

    # Add nodes (14 ft = 168 in apart)
    TwoSpanBeam.AddNode("N1", 0, 0, 0)
    TwoSpanBeam.AddNode("N2", length, 0, 0)
    TwoSpanBeam.AddNode("N3", length * 2, 0, 0)

    # Add a beam with the following properties:
    # E = 29000 ksi, G = 11200 ksi, Iy = 100 in^4, Iz = 150 in^4, J = 250 in^4, A = 20 in^2
    TwoSpanBeam.AddMember("M1",
                          "N1",
                          "N2",
                          E=29000,
                          G=11200,
                          Iy=100,
                          Iz=150,
                          J=250,
                          A=20)
    TwoSpanBeam.AddMember("M2",
                          "N2",
                          "N3",
                          E=29000,
                          G=11200,
                          Iy=100,
                          Iz=150,
                          J=250,
                          A=20)

    # Supports: Pin, Roller, Roller
    TwoSpanBeam.DefineSupport("N1",
                              SupportDX=True,
                              SupportDY=True,
                              SupportDZ=True,
                              SupportRX=True)
    TwoSpanBeam.DefineSupport("N2",
                              SupportDX=False,
                              SupportDY=True,
                              SupportDZ=True,
                              SupportRX=True)
    TwoSpanBeam.DefineSupport("N3",
                              SupportDX=False,
                              SupportDY=True,
                              SupportDZ=True,
                              SupportRX=True)

    return TwoSpanBeam
示例#19
0
def three_member_frame_1():
    MomentFrame = FEModel3D()

    # Add nodes (frame is 15 ft wide x 12 ft tall)
    MomentFrame.AddNode("N1", 0, 0, 0)
    MomentFrame.AddNode("N2", 0, 12 * 12, 0)
    MomentFrame.AddNode("N3", 15 * 12, 12 * 12, 0)
    MomentFrame.AddNode("N4", 15 * 12, 0 * 12, 0)

    # Add columns with the following properties:
    # AISC W8x31
    # E = 29000 ksi, G = 11200 ksi, Iy = 37.1 in^4, Iz = 110 in^4, J = 0.536 in^4, A = 9.13 in^2
    MomentFrame.AddMember("M1",
                          "N1",
                          "N2",
                          E=29000,
                          G=11200,
                          Iy=37.1,
                          Iz=110,
                          J=0.536,
                          A=9.13)
    MomentFrame.AddMember("M2",
                          "N4",
                          "N3",
                          E=29000,
                          G=11200,
                          Iy=37.1,
                          Iz=110,
                          J=0.536,
                          A=9.13)
    MomentFrame.AddMember("M3",
                          "N2",
                          "N3",
                          E=29000,
                          G=11200,
                          Iy=37.1,
                          Iz=110,
                          J=0.536,
                          A=9.13)

    # Provide fixed supports at the bases of the columns
    MomentFrame.DefineSupport("N1", True, True, True, True, True, True)
    MomentFrame.DefineSupport("N4", True, True, True, True, True, True)

    return MomentFrame
示例#20
0
 def test_end_release_Rz(self):
     myModel = FEModel3D()
     # Add two supported nodes and one member
     myModel.AddNode('N1', 0, 0, 0)
     myModel.AddNode('N2', 10 * 12, 0, 0)
     myModel.DefineSupport('N1', True, True, True, True, True, True)
     myModel.DefineSupport('N2', True, True, True, True, True, True)
     myModel.AddMember('M1', 'N1', 'N2', 29000, 11400, 100, 150, 250, 10)
     # Release Rzi and Rzj on member M1
     myModel.DefineReleases('M1', False, False, False, False, False, True, \
                                 False, False, False, False, False, True)
     # Add a load
     myModel.AddMemberDistLoad('M1', 'Fy', -0.5, -0.5)
     myModel.Analyze()
     # Get the resulting moments
     calculated_moment = myModel.GetMember('M1').MinMoment('Mz')
     expected_moment = -0.5 * (10 * 12)**2 / 8
     self.assertAlmostEqual(calculated_moment, expected_moment)
示例#21
0
 def test_end_release_Rz(self):
     myModel = FEModel3D()
     # Add two supported nodes and one member
     myModel.add_node('N1', 0, 0, 0)
     myModel.add_node('N2', 10 * 12, 0, 0)
     myModel.def_support('N1', True, True, True, True, True, True)
     myModel.def_support('N2', True, True, True, True, True, True)
     myModel.add_member('M1', 'N1', 'N2', 29000, 11400, 100, 150, 250, 10)
     # Release Rzi and Rzj on member M1
     myModel.def_releases('M1', False, False, False, False, False, True, \
                                 False, False, False, False, False, True)
     # Add a load
     myModel.add_member_dist_load('M1', 'Fy', -0.5, -0.5)
     myModel.analyze()
     # Get the resulting moments
     calculated_moment = myModel.Members['M1'].min_moment('Mz')
     expected_moment = -0.5 * (10 * 12)**2 / 8
     self.assertAlmostEqual(calculated_moment, expected_moment)
示例#22
0
def two_member_frame_2():
    # Two member frame with sloping beam up to flat beam. Flat beam is on right.
    # Frame is taken from Example 16.2 in textbook "Structural Analysis" by R.C. Hibbeler (8th Ed.)
    Frame = FEModel3D()

    Frame.AddNode("N1", X=0, Y=0, Z=0)
    Frame.AddNode("N2", X=20 * 12, Y=15 * 12, Z=0)
    Frame.AddNode("N3", X=20 * 12 + 20 * 12, Y=15 * 12, Z=0)

    Frame.AddMember("M1",
                    "N1",
                    "N2",
                    E=29000,
                    G=11200,
                    Iy=150,
                    Iz=600,
                    J=2,
                    A=12)
    Frame.AddMember("M2",
                    "N2",
                    "N3",
                    E=29000,
                    G=11200,
                    Iy=150,
                    Iz=600,
                    J=2,
                    A=12)

    # N1: Fixed, N3: Fixed
    Frame.DefineSupport("N1",
                        SupportDX=True,
                        SupportDY=True,
                        SupportDZ=True,
                        SupportRX=True,
                        SupportRZ=True)
    Frame.DefineSupport("N3",
                        SupportDX=True,
                        SupportDY=True,
                        SupportDZ=True,
                        SupportRX=True,
                        SupportRZ=True)

    return Frame
示例#23
0
def two_member_frame_1():
    # Two member frame with one beam and one column. Column is on right.
    # Frame is taken from Example 16.1 in textbook "Structural Analysis" by R.C. Hibbeler (8th Ed.)
    Frame = FEModel3D()

    Frame.AddNode("N1", X=0, Y=20 * 12, Z=0)
    Frame.AddNode("N2", X=20 * 12, Y=20 * 12, Z=0)
    Frame.AddNode("N3", X=20 * 12, Y=0, Z=0)

    Frame.AddMember("M1",
                    "N1",
                    "N2",
                    E=29000,
                    G=11200,
                    Iy=150,
                    Iz=500,
                    J=2,
                    A=10)
    Frame.AddMember("M2",
                    "N2",
                    "N3",
                    E=29000,
                    G=11200,
                    Iy=150,
                    Iz=500,
                    J=2,
                    A=10)

    # N1: Roller, N3: Fixed
    Frame.DefineSupport("N1",
                        SupportDX=False,
                        SupportDY=True,
                        SupportDZ=True,
                        SupportRX=True)
    Frame.DefineSupport("N3",
                        SupportDX=True,
                        SupportDY=True,
                        SupportDZ=True,
                        SupportRX=True,
                        SupportRZ=True)

    return Frame
示例#24
0
 def test_support_settlement(self):
     beam = FEModel3D()
     # Add nodes
     beam.AddNode('A', 0, 0, 0)
     beam.AddNode('B', 20 * 12, 0, 0)
     beam.AddNode('C', 40 * 12, 0, 0)
     beam.AddNode('D', 60 * 12, 0, 0)
     # Add members
     A = 20
     E = 29000
     G = 11400
     Iy = 1000
     Iz = 7800
     J = 8800
     beam.AddMember('AB', 'A', 'B', E, G, Iy, Iz, J, A)
     beam.AddMember('BC', 'B', 'C', E, G, Iy, Iz, J, A)
     beam.AddMember('CD', 'C', 'D', E, G, Iy, Iz, J, A)
     # Provide supports
     beam.DefineSupport('A', True, True, True, True, False, False)
     beam.DefineSupport('B', False, True, True, False, False, False)
     beam.DefineSupport('C', False, True, True, False, False, False)
     beam.DefineSupport('D', False, True, True, False, False, False)
     # Add a uniform load to the beam
     beam.AddMemberDistLoad('AB', 'Fy', -2 / 12, -2 / 12)
     beam.AddMemberDistLoad('BC', 'Fy', -2 / 12, -2 / 12)
     beam.AddMemberDistLoad('CD', 'Fy', -2 / 12, -2 / 12)
     # Add support settlements
     beam.AddNodeDisplacement('B', 'DY', -5 / 8)
     beam.AddNodeDisplacement('C', 'DY', -1.5)
     beam.AddNodeDisplacement('D', 'DY', -0.75)
     # Analyze the beam
     beam.Analyze()
     # subTest context manager prints which portion fails, if any
     correct_values = [('A', -1.098), ('B', 122.373), ('C', -61.451),
                       ('D', 60.176)]
     for name, value in correct_values:
         with self.subTest(node=name):
             calculated_Rxn = beam.GetNode(name).RxnFY['Combo 1']
             # Two decimal place accuracy requires +/-0.5% accuracy
             # one decimal place requires +/-5%
             self.assertAlmostEqual(calculated_Rxn / value, 1.0, 2)
示例#25
0
    def test_spring_elements(self): 
        # A First Course in the Finite Element Method, 4th Edition
        # Daryl L. Logan
        # Example 2.1
        # Units for this model are pounds and inches
        system = FEModel3D()
        system.add_node('1', 0, 0, 0)
        system.add_node('2', 30, 0, 0)
        system.add_node('3', 10, 0, 0)
        system.add_node('4', 20, 0, 0)
        # Add spring members
        system.add_spring('S1', '1', '3', 1000)
        system.add_spring('S2', '3', '4', 2000)
        system.add_spring('S3', '4', '2', 3000)
        # Define supports
        system.def_support('1', True, True, True, True, True, True)
        system.def_support('2', True, True, True, True, True, True)
        system.def_support('3', False, True, True, True, True, True)
        system.def_support('4', False, True, True, True, True, True)
        # Add node loads
        system.add_node_load('4', 'FX', 5000)
        system.analyze(True)
        # Check results
        # correct_values = [('3', 0.9090909090909092),
        #                   ('4', 1.3636363636363638),
        #                   ('1', -909.0909090909091),
        #                   ('2', -4090.9090909090914)]
        n3_DX = system.Nodes['3'].DX['Combo 1']
        self.assertAlmostEqual(n3_DX/ 0.9090909090909092, 1.0, 2)

        n4_DX = system.Nodes['4'].DX['Combo 1']
        self.assertAlmostEqual(n4_DX/1.3636363636363638, 1.0, 2)
        
        n1_rxn = system.Nodes['1'].RxnFX['Combo 1']
        self.assertAlmostEqual(n1_rxn/-909.0909090909091, 1.0, 2)
        
        n2_rxn = system.Nodes['2'].RxnFX['Combo 1']
        self.assertAlmostEqual(n2_rxn/-4090.9090909090914, 1.0, 2)
        
示例#26
0
    def test_cracked_rect_shear_wall(self):

        sw = FEModel3D()

        E = 57000*(4000)**0.5/1000*12**2
        nu = 0.17
        G = E/(2*(1 + nu))
        t = 1
        L = 10
        H = 20
        A = L*t
        I = 0.35*t*L**3/12

        mesh_size = 1
        mesh = RectangleMesh(mesh_size, L, H, t, E, nu, ky_mod=0.35, element_type='Rect')
        mesh.generate()

        sw.add_mesh(mesh)

        V = 1000
        for node in sw.Nodes.values():
            if node.Y == 0:
                sw.def_support(node.name, True, True, True, True, True, True)
            elif node.Y == H:
                sw.add_node_load(node.name, 'FX', V/11)
        
        sw.analyze()

        # Calculated solution
        delta1 = max([node.DX['Combo 1'] for node in sw.Nodes.values()])

        # Theoretical solution
        delta2 = V*H**3/(3*E*I) + 1.2*V*H/(G*A)
        
        # Check that the solution matches the theoretical solution within 2%
        self.assertLess(abs(1 - delta1/delta2), 0.02, 'Failed cracked rect plate shear wall test.')
# -*- coding: utf-8 -*-
"""
Created on Sun Sep 16 14:43:31 2018

@author: craig
"""
# Example of a simply supported beam with a point load.
# Units used in this example are inches, and kips

# Import `FEModel3D` from `PyNite`
from PyNite import FEModel3D

# Create a new finite element model
SimpleBeam = FEModel3D()

# Add nodes (14 ft = 168 in apart)
SimpleBeam.AddNode("N1", 0, 0, 0)
SimpleBeam.AddNode("N2", 168, 0, 0)

# Add a beam with the following properties:
# E = 29000 ksi, G = 11400 ksi, Iy = 100 in^4, Iz = 150 in^4, J = 250 in^4, A = 20 in^2
SimpleBeam.AddMember("M1", "N1", "N2", 29000, 11400, 100, 150, 250, 20)

# Provide simple supports
SimpleBeam.DefineSupport("N1", True, True, True, True, False, False)
SimpleBeam.DefineSupport("N2", True, True, True, True, False, False)

# Add a point load of 5 kips at the midspan of the beam
SimpleBeam.AddMemberPtLoad("M1", "Fy", 5, 7 * 12)

# Analyze the beam
示例#28
0
# A First Course in the Finite Element Method, 4th Edition
# Daryl L. Logan
# Example 5.8
# Units for this model are kips and inches

# Import 'FEModel3D' and 'Visualization' from 'PyNite'
from PyNite import FEModel3D
from PyNite import Visualization

# Create a new model
frame = FEModel3D()

# Define the nodes
frame.AddNode('N1', 0, 0, 0)
frame.AddNode('N2', -100, 0, 0)
frame.AddNode('N3', 0, 0, -100)
frame.AddNode('N4', 0, -100, 0)

# Define the supports
frame.DefineSupport('N2', True, True, True, True, True, True)
frame.DefineSupport('N3', True, True, True, True, True, True)
frame.DefineSupport('N4', True, True, True, True, True, True)

# Create members (all members will have the same properties in this example)
J = 50
Iy = 100
Iz = 100
E = 30000
G = 10000
A = 10
示例#29
0
# Example of a basic 2D tension-only braced frame with gravity and lateral
# loads. Units used for the model in this example are inches and kips

# Import `FEModel3D` from `PyNite`
from PyNite import FEModel3D

# Create a new finite element model
BracedFrame = FEModel3D()

# Add nodes (frame is 15 ft wide x 12 ft tall)
BracedFrame.AddNode('N1', 0, 0, 0)
BracedFrame.AddNode('N2', 0, 12 * 12, 0)
BracedFrame.AddNode('N3', 15 * 12, 12 * 12, 0)
BracedFrame.AddNode('N4', 15 * 12, 0 * 12, 0)

# Define column properties (use W10x33 from the AISC Manual):
E = 29000  # ksi
G = 11400  # ksi
Iy = 36.6  # in^4
Iz = 171  # in^4
J = 0.58  # in^4
A = 9.71  # in^2

# Define the columns
BracedFrame.AddMember('Col1', 'N1', 'N2', E, G, Iy, Iz, J, A)
BracedFrame.AddMember('Col2', 'N4', 'N3', E, G, Iy, Iz, J, A)

# Define beam properties (Use W8x24)
Iy = 18.3  # in^4
Iz = 82.7  # in^4
J = 0.346  # in^4
                     nu,
                     kx_mod=1,
                     ky_mod=1,
                     origin=[0, 0, 0],
                     plane='XY',
                     start_node='N1',
                     start_element='Q1',
                     element_type='Quad')

# Generate the mesh. Rectangle meshes won't generate unless you tell them to.
# This allows you to add openings to them before meshing.
mesh.generate()

# Create a finite element model
from PyNite import FEModel3D
model = FEModel3D()

# Add the mesh to the model
model.add_mesh(mesh)

# Step through each quadrilateral in the model
for element in model.Quads.values():
    # Add loads to the element
    model.add_quad_surface_pressure(element.name, load, case='W')

# Add fully fixed supports on all side of the wall
for node in model.Nodes.values():
    if (round(node.Y, 10) == 0 or round(node.Y, 10) == height
            or round(node.X, 10) == 0 or round(node.X, 10) == width):
        model.def_support(node.name, True, True, True, True, True, True)