def test_example2_1(self): nodes = [] # list holding the node objects elements = [] # list holding the element objects # create 2d frame analysis object analysis = FrameAnalysis2D() # create sections steel = Steel() section1 = Section(area=6000) section2 = Section(area=8000) # create nodes nodes.append(analysis.create_node(coords=[0, 0])) nodes.append(analysis.create_node(coords=[6000, 4000])) nodes.append(analysis.create_node(coords=[9000, 0])) # create truss elements elements.append(analysis.create_element( el_type='Bar2-2D', nodes=[nodes[0], nodes[1]], material=steel, section=section1 )) elements.append(analysis.create_element( el_type='Bar2-2D', nodes=[nodes[1], nodes[2]], material=steel, section=section2 )) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=nodes[0], val=0, dof=0) freedom_case.add_nodal_support(node=nodes[0], val=0, dof=1) freedom_case.add_nodal_support(node=nodes[2], val=0, dof=0) freedom_case.add_nodal_support(node=nodes[2], val=0, dof=1) # add loads load_case = cases.LoadCase() load_case.add_nodal_load(node=nodes[1], val=500e3, dof=0) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check node displacement n1_disp = nodes[1].get_displacements(analysis_case) u = n1_disp[0] v = n1_disp[1] self.assertEqual(np.around(u, 2), 2.41) self.assertEqual(np.around(v, 2), 0.72) # check axial forces (_, n1) = elements[0].get_afd(n=1, analysis_case=analysis_case) (_, n2) = elements[1].get_afd(n=1, analysis_case=analysis_case) self.assertEqual(np.around(n1/1e3, 1), 400.6) self.assertEqual(np.around(n2/1e3, 1), -277.8)
def test_example2_3(self): # create 2d frame analysis object analysis = FrameAnalysis2D() # create sections steel = Steel() section1 = Section(area=4000) section2 = Section(area=1000) # create nodes a = analysis.create_node(coords=[0, 0]) b = analysis.create_node(coords=[2000, 2000]) c = analysis.create_node(coords=[-4000, 2000]) # create truss elements el1 = analysis.create_element( el_type='Bar2-2D', nodes=[c, a], material=steel, section=section1) el2 = analysis.create_element( el_type='Bar2-2D', nodes=[a, b], material=steel, section=section2) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=b, val=0, dof=0) freedom_case.add_nodal_support(node=b, val=0, dof=1) freedom_case.add_nodal_support(node=c, val=0, dof=0) freedom_case.add_nodal_support(node=c, val=0, dof=1) sup1 = freedom_case.add_nodal_support(node=a, val=0, dof=0) sup2 = freedom_case.add_nodal_support(node=a, val=-5, dof=1) # add loads load_case = cases.LoadCase() # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check reactions self.assertEqual(np.around(sup1.get_reaction(analysis_case)/1e3, 1), 181.0) self.assertEqual(np.around(sup2.get_reaction(analysis_case)/1e3, 1), -355.7)
def setUp(self): # create materials steel = Steel() # create 2d frame analysis object self.analysis = FrameAnalysis2D() section1 = Section(area=6e3, ixx=200e6) section2 = Section(area=4e3, ixx=50e6) # create nodes self.node_a = self.analysis.create_node(coords=[0]) self.node_b = self.analysis.create_node(coords=[8000]) self.node_c = self.analysis.create_node(coords=[13000]) # create beam elements self.element_ab = self.analysis.create_element( el_type='EB2-2D', nodes=[self.node_a, self.node_b], material=steel, section=section1 ) self.element_bc = self.analysis.create_element( el_type='EB2-2D', nodes=[self.node_b, self.node_c], material=steel, section=section2 )
def test_fig8(self): """Simple Beam – Concentrated Load at Any Point""" a = self.length * np.random.uniform(0.1, 0.9) b = self.length - a # create 2d frame analysis object analysis = FrameAnalysis2D() # create section section = Section(ixx=self.ixx) # create nodes node_a = analysis.create_node(coords=[0]) node_b = analysis.create_node(coords=[a]) node_c = analysis.create_node(coords=[self.length]) # create beam elements element_ab = analysis.create_element(el_type='EB2-2D', nodes=[node_a, node_b], material=self.steel, section=section) element_bc = analysis.create_element(el_type='EB2-2D', nodes=[node_b, node_c], material=self.steel, section=section) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=node_a, val=0, dof=0) freedom_case.add_nodal_support(node=node_a, val=0, dof=1) freedom_case.add_nodal_support(node=node_c, val=0, dof=1) # add loads load_case = cases.LoadCase() load_case.add_nodal_load(node=node_b, val=self.pl, dof=1) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check displacements def analytical_disp_ab(x): factor = self.pl * b * x / 6 / self.elastic_modulus / self.ixx / self.length l0 = self.length return factor * (l0 * l0 - b * b - x * x) def analytical_disp_bc(x): l0 = self.length factor = self.pl * a * ( l0 - x) / 6 / self.elastic_modulus / self.ixx / l0 return factor * (2 * l0 * x - a * a - x * x) # get displacements displacements_ab = element_ab.get_displacements(21, analysis_case) displacements_bc = element_bc.get_displacements(21, analysis_case) # loop through each station for disp in displacements_ab: xi = disp[0] x = a * xi v = disp[2] # check displacements self.assertTrue(np.isclose(v, analytical_disp_ab(x), atol=1e-06)) # loop through each station for disp in displacements_bc: xi = disp[0] x = b * xi + a v = disp[2] # check displacements self.assertTrue(np.isclose(v, analytical_disp_bc(x), atol=1e-06)) # check max displacement if a > b: aa = a bb = b disps = displacements_ab else: aa = b bb = a disps = displacements_bc l0 = self.length v_max = (self.pl * aa * bb * (aa + 2 * bb) * np.sqrt(3 * aa * (aa + 2 * bb))) / ( 27 * self.elastic_modulus * self.ixx * l0) # check value self.assertTrue( np.isclose(abs(v_max), max(np.abs(disps[:, 2])), atol=1e-06)) # check position of max displacement pos = np.sqrt((aa * (aa + 2 * bb)) / 3) if b > a: pos = self.length - pos x = 1 / b * (pos - a) else: x = pos / a self.assertTrue( np.isclose(x, disps[np.abs(disps[:, 2]).argmax(), 0], atol=1e-06)) # check displacement at point load v_ab = self.pl * a * a * b * b / 3 / self.elastic_modulus / self.ixx / self.length self.assertTrue(np.isclose(v_ab, displacements_bc[0, 2], atol=1e-06)) # check bending moments def analytical_bmd_ab(x): return self.pl * b * x / self.length def analytical_bmd_bc(x): x = self.length - x return self.pl * a * x / self.length # get bmd (xis_ab, bmd_ab) = element_ab.get_bmd(11, analysis_case) (xis_bc, bmd_bc) = element_bc.get_bmd(11, analysis_case) # loop through each station for (i, m) in enumerate(bmd_ab): xi = xis_ab[i] x = a * xi # check bending moment self.assertTrue(np.isclose(m, analytical_bmd_ab(x), atol=1e-06)) # loop through each station for (i, m) in enumerate(bmd_bc): xi = xis_bc[i] x = a + b * xi # check bending moment self.assertTrue(np.isclose(m, analytical_bmd_bc(x), atol=1e-06)) # check max bending moment m_max = self.pl * a * b / self.length # check value self.assertTrue(np.isclose(abs(m_max), max(np.abs(bmd_ab)), atol=1e-06)) # check position self.assertTrue( np.isclose(1, xis_ab[np.abs(bmd_ab).argmax()], atol=1e-06)) # check shear force def analytical_sfd_ab(x): return -self.pl * b / self.length def analytical_sfd_bc(x): return self.pl * a / self.length # get sfd (xis, sfd_ab) = element_ab.get_sfd(11, analysis_case) (xis, sfd_bc) = element_bc.get_sfd(11, analysis_case) # loop through each station for (i, sf) in enumerate(sfd_ab): xi = xis_ab[i] x = a * xi # check shear force self.assertTrue(np.isclose(sf, analytical_sfd_ab(x), atol=1e-06)) # loop through each station for (i, sf) in enumerate(sfd_bc): xi = xis_bc[i] x = a + b * xi # check shear force self.assertTrue(np.isclose(sf, analytical_sfd_bc(x), atol=1e-06))
def test_fig7(self): """Simple Beam – Concentrated Load at Center""" # create 2d frame analysis object analysis = FrameAnalysis2D() # create section section = Section(ixx=self.ixx) # create nodes node_a = analysis.create_node(coords=[0]) node_b = analysis.create_node(coords=[self.length * 0.5]) node_c = analysis.create_node(coords=[self.length]) # create beam elements element_ab = analysis.create_element(el_type='EB2-2D', nodes=[node_a, node_b], material=self.steel, section=section) element_bc = analysis.create_element(el_type='EB2-2D', nodes=[node_b, node_c], material=self.steel, section=section) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=node_a, val=0, dof=0) freedom_case.add_nodal_support(node=node_a, val=0, dof=1) freedom_case.add_nodal_support(node=node_c, val=0, dof=1) # add loads load_case = cases.LoadCase() load_case.add_nodal_load(node=node_b, val=self.pl, dof=1) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check displacements def analytical_disp_ab(x): factor = self.pl * x / 48 / self.elastic_modulus / self.ixx l0 = self.length return factor * (3 * l0 * l0 - 4 * x * x) def analytical_disp_bc(x): x = self.length - x factor = self.pl * x / 48 / self.elastic_modulus / self.ixx l0 = self.length return factor * (3 * l0 * l0 - 4 * x * x) # get displacements displacements_ab = element_ab.get_displacements(11, analysis_case) displacements_bc = element_bc.get_displacements(11, analysis_case) # loop through each station for disp in displacements_ab: xi = disp[0] x = self.length * 0.5 * xi v = disp[2] # check displacements self.assertTrue(np.isclose(v, analytical_disp_ab(x), atol=1e-06)) # loop through each station for disp in displacements_bc: xi = disp[0] x = self.length * 0.5 + self.length * 0.5 * xi v = disp[2] # check displacements self.assertTrue(np.isclose(v, analytical_disp_bc(x), atol=1e-06)) # check max displacement l0 = self.length v_max = self.pl * l0 * l0 * l0 / 48 / self.elastic_modulus / self.ixx # check value self.assertTrue( np.isclose(abs(v_max), max(np.abs(displacements_ab[:, 2])), atol=1e-06)) # check position self.assertTrue( np.isclose(1, displacements_ab[np.abs(displacements_ab[:, 2]).argmax(), 0], atol=1e-06)) # check bending moments def analytical_bmd_ab(x): return self.pl * x / 2 def analytical_bmd_bc(x): x = self.length - x return self.pl * x / 2 # get bmd (xis_ab, bmd_ab) = element_ab.get_bmd(11, analysis_case) (xis_bc, bmd_bc) = element_bc.get_bmd(11, analysis_case) # loop through each station for (i, m) in enumerate(bmd_ab): xi = xis_ab[i] x = self.length * 0.5 * xi # check bending moment self.assertTrue(np.isclose(m, analytical_bmd_ab(x), atol=1e-06)) # loop through each station for (i, m) in enumerate(bmd_bc): xi = xis_bc[i] x = self.length * 0.5 + self.length * 0.5 * xi # check bending moment self.assertTrue(np.isclose(m, analytical_bmd_bc(x), atol=1e-06)) # check max bending moment l0 = self.length m_max = self.pl * l0 / 4 # check value self.assertTrue(np.isclose(abs(m_max), max(np.abs(bmd_ab)), atol=1e-06)) # check position self.assertTrue( np.isclose(1, xis_ab[np.abs(bmd_ab).argmax()], atol=1e-06)) # check shear force def analytical_sfd_ab(x): return -self.pl / 2 def analytical_sfd_bc(x): return self.pl / 2 # get sfd (xis, sfd_ab) = element_ab.get_sfd(11, analysis_case) (xis, sfd_bc) = element_bc.get_sfd(11, analysis_case) # loop through each station for (i, sf) in enumerate(sfd_ab): xi = xis_ab[i] x = self.length * 0.5 * xi # check shear force self.assertTrue(np.isclose(sf, analytical_sfd_ab(x), atol=1e-06)) # loop through each station for (i, sf) in enumerate(sfd_bc): xi = xis_bc[i] x = self.length * 0.5 + self.length * 0.5 * xi # check shear force self.assertTrue(np.isclose(sf, analytical_sfd_bc(x), atol=1e-06))
def test_fig4(self): """Simple Beam – Uniform Load Partially Distributed at Each End""" a = self.length * np.random.uniform(0.1, 0.4) c = self.length * np.random.uniform(0.1, 0.4) b = self.length - a - c q2 = -np.random.uniform(1, 10) # create 2d frame analysis object analysis = FrameAnalysis2D() # create section section = Section(ixx=self.ixx) # create nodes node_a = analysis.create_node(coords=[0]) node_b = analysis.create_node(coords=[a]) node_c = analysis.create_node(coords=[a + b]) node_d = analysis.create_node(coords=[self.length]) # create beam elements element_ab = analysis.create_element(el_type='EB2-2D', nodes=[node_a, node_b], material=self.steel, section=section) element_bc = analysis.create_element(el_type='EB2-2D', nodes=[node_b, node_c], material=self.steel, section=section) element_cd = analysis.create_element(el_type='EB2-2D', nodes=[node_c, node_d], material=self.steel, section=section) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=node_a, val=0, dof=0) sup1 = freedom_case.add_nodal_support(node=node_a, val=0, dof=1) sup2 = freedom_case.add_nodal_support(node=node_d, val=0, dof=1) # add loads load_case = cases.LoadCase() load_case.add_element_load(element_ab.generate_udl(q=self.q)) load_case.add_element_load(element_cd.generate_udl(q=q2)) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check reactions r1 = -sup1.get_reaction(analysis_case) r1_ana = (self.q * a * (2 * self.length - a) + q2 * c * c) / (2 * self.length) r2 = -sup2.get_reaction(analysis_case) r2_ana = (q2 * c * (2 * self.length - c) + self.q * a * a) / (2 * self.length) self.assertTrue(np.isclose(r1, r1_ana, atol=1e-06)) self.assertTrue(np.isclose(r2, r2_ana, atol=1e-06)) # check bending moments def analytical_bmd_ab(x): return r1 * x - self.q * 0.5 * x * x def analytical_bmd_bc(x): return r1 * x - self.q * a * 0.5 * (2 * x - a) def analytical_bmd_cd(x): return r2 * (self.length - x) - q2 * (self.length - x) * (self.length - x) * 0.5 # get bmds (xis_ab, bmd_ab) = element_ab.get_bmd(11, analysis_case) (xis_bc, bmd_bc) = element_bc.get_bmd(11, analysis_case) (xis_cd, bmd_cd) = element_cd.get_bmd(11, analysis_case) # element_ab - loop through each station for (i, m) in enumerate(bmd_ab): xi = xis_ab[i] x = a * xi # check bending moments self.assertTrue(np.isclose(m, analytical_bmd_ab(x), atol=1e-06)) # element_bc - loop through each station for (i, m) in enumerate(bmd_bc): xi = xis_bc[i] x = b * xi + a # check bending moments self.assertTrue(np.isclose(m, analytical_bmd_bc(x), atol=1e-06)) # element_cd - loop through each station for (i, m) in enumerate(bmd_cd): xi = xis_cd[i] x = c * xi + a + b # check bending moments self.assertTrue(np.isclose(m, analytical_bmd_cd(x), atol=1e-06)) # check max bending moment if abs(r1) < abs(self.q * a): m_max = r1 * r1 / 2 / self.q pos = r1 / self.q x = pos / a # check value self.assertTrue( np.isclose(abs(m_max), max(np.abs(bmd_ab)), atol=1e-06)) # check position self.assertTrue( np.isclose(x, xis_ab[np.abs(bmd_ab).argmax()], atol=1e-06)) if abs(r2) < abs(q2 * c): m_max = r2 * r2 / 2 / q2 pos = self.length - r2 / q2 x = 1 / c * (pos - a - b) # check value self.assertTrue( np.isclose(abs(m_max), max(np.abs(bmd_cd)), atol=1e-06)) # check position self.assertTrue( np.isclose(x, xis_cd[np.abs(bmd_cd).argmax()], atol=1e-06)) # check shear force def analytical_sfd_ab(x): return -r1 + self.q * x def analytical_sfd_bc(x): return -r1 + self.q * a def analytical_sfd_cd(x): return r2 - q2 * (self.length - x) # get sfds (xis_ab, sfd_ab) = element_ab.get_sfd(11, analysis_case) (xis_bc, sfd_bc) = element_bc.get_sfd(11, analysis_case) (xis_cd, sfd_cd) = element_cd.get_sfd(11, analysis_case) # element_ab - loop through each station for (i, sf) in enumerate(sfd_ab): xi = xis_ab[i] x = a * xi # check shear forces self.assertTrue(np.isclose(sf, analytical_sfd_ab(x), atol=1e-06)) # element_bc - loop through each station for (i, sf) in enumerate(sfd_bc): xi = xis_bc[i] x = b * xi + a # check shear forces self.assertTrue(np.isclose(sf, analytical_sfd_bc(x), atol=1e-06)) # element_cd - loop through each station for (i, sf) in enumerate(sfd_cd): xi = xis_cd[i] x = c * xi + a + b # check shear forces self.assertTrue(np.isclose(sf, analytical_sfd_cd(x), atol=1e-06))
def test_fig3(self): """Simple Beam – Uniform Load Partially Distributed at One End""" a = self.length * np.random.uniform(0.1, 0.9) # create 2d frame analysis object analysis = FrameAnalysis2D() # create section section = Section(ixx=self.ixx) # create nodes node_a = analysis.create_node(coords=[0]) node_b = analysis.create_node(coords=[a]) node_c = analysis.create_node(coords=[self.length]) # create beam elements element_ab = analysis.create_element(el_type='EB2-2D', nodes=[node_a, node_b], material=self.steel, section=section) element_bc = analysis.create_element(el_type='EB2-2D', nodes=[node_b, node_c], material=self.steel, section=section) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=node_a, val=0, dof=0) sup1 = freedom_case.add_nodal_support(node=node_a, val=0, dof=1) sup2 = freedom_case.add_nodal_support(node=node_c, val=0, dof=1) # add loads load_case = cases.LoadCase() load_case.add_element_load(element_ab.generate_udl(q=self.q)) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check reactions r1 = -sup1.get_reaction(analysis_case) r2 = -sup2.get_reaction(analysis_case) self.assertTrue( np.isclose(r1, self.q * a / 2 / self.length * (2 * self.length - a), atol=1e-06)) self.assertTrue( np.isclose(r2, self.q * a * a / 2 / self.length, atol=1e-06)) # check displacements def analytical_disp_ab(x): l0 = self.length factor = self.q * x / 24 / self.elastic_modulus / self.ixx / l0 return factor * (a * a * (2 * l0 - a) * (2 * l0 - a) - 2 * a * x * x * (2 * l0 - a) + l0 * x * x * x) def analytical_disp_bc(x): l0 = self.length factor = self.q * a * a * ( l0 - x) / 24 / self.elastic_modulus / self.ixx / l0 return factor * (4 * x * l0 - 2 * x * x - a * a) # get displacements displacements_ab = element_ab.get_displacements(11, analysis_case) displacements_bc = element_bc.get_displacements(11, analysis_case) # loop through each station for disp in displacements_ab: xi = disp[0] x = a * xi v = disp[2] # check displacements self.assertTrue(np.isclose(v, analytical_disp_ab(x), atol=1e-06)) # loop through each station for disp in displacements_bc: xi = disp[0] x = (self.length - a) * xi + a v = disp[2] # check displacements self.assertTrue(np.isclose(v, analytical_disp_bc(x), atol=1e-06)) # check bending moments def analytical_bmd_ab(x): return r1 * x - self.q * x * x / 2 def analytical_bmd_bc(x): return r2 * (self.length - x) # get bmds (xis_ab, bmd_ab) = element_ab.get_bmd(11, analysis_case) (xis_bc, bmd_bc) = element_bc.get_bmd(11, analysis_case) # element_ab - loop through each station for (i, m) in enumerate(bmd_ab): xi = xis_ab[i] x = a * xi # check bending moments self.assertTrue(np.isclose(m, analytical_bmd_ab(x), atol=1e-06)) # element_bc - loop through each station for (i, m) in enumerate(bmd_bc): xi = xis_bc[i] x = (self.length - a) * xi + a # check bending moments self.assertTrue(np.isclose(m, analytical_bmd_bc(x), atol=1e-06)) # check max bending moment m_max = r1 * r1 / 2 / self.q pos = r1 / self.q x = pos / a # check value self.assertTrue(np.isclose(abs(m_max), max(np.abs(bmd_ab)), atol=1e-06)) # check position self.assertTrue( np.isclose(x, xis_ab[np.abs(bmd_ab).argmax()], atol=1e-06)) # check shear force def analytical_sfd_ab(x): return -r1 + self.q * x def analytical_sfd_bc(x): return r2 # get sfds (xis_ab, sfd_ab) = element_ab.get_sfd(11, analysis_case) (xis_bc, sfd_bc) = element_bc.get_sfd(11, analysis_case) # element_ab - loop through each station for (i, sf) in enumerate(sfd_ab): xi = xis_ab[i] x = a * xi # check shear forces self.assertTrue(np.isclose(sf, analytical_sfd_ab(x), atol=1e-06)) # element_bc - loop through each station for (i, sf) in enumerate(sfd_bc): xi = xis_bc[i] x = (self.length - a) * xi + a # check shear forces self.assertTrue(np.isclose(sf, analytical_sfd_bc(x), atol=1e-06))
def test_fig1(self): """Simple Beam – Uniformly Distributed Load""" # create 2d frame analysis object analysis = FrameAnalysis2D() # create section section = Section(ixx=self.ixx) # create nodes node_a = analysis.create_node(coords=[0]) node_b = analysis.create_node(coords=[self.length]) # create beam elements element = analysis.create_element(el_type='EB2-2D', nodes=[node_a, node_b], material=self.steel, section=section) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=node_a, val=0, dof=0) freedom_case.add_nodal_support(node=node_a, val=0, dof=1) freedom_case.add_nodal_support(node=node_b, val=0, dof=1) # add loads load_case = cases.LoadCase() load_case.add_element_load(element.generate_udl(q=self.q)) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check displacements def analytical_disp(x): factor = self.q * x / 24 / self.elastic_modulus / self.ixx l0 = self.length return factor * (l0 * l0 * l0 - 2 * l0 * x * x + x * x * x) # get displacements displacements = element.get_displacements(11, analysis_case) # loop through each station for disp in displacements: xi = disp[0] x = self.length * xi v = disp[2] # check displacements self.assertTrue(np.isclose(v, analytical_disp(x), atol=1e-06)) # check max displacement l0 = self.length v_max = 5 * self.q * l0 * l0 * l0 * l0 / 384 / self.elastic_modulus / self.ixx # check value self.assertTrue( np.isclose(abs(v_max), max(np.abs(displacements[:, 2])))) # check position self.assertTrue( np.isclose(0.5, displacements[np.abs(displacements[:, 2]).argmax(), 0], atol=1e-06)) # check bending moments def analytical_bmd(x): return self.q * x / 2 * (self.length - x) # get bmd (xis, bmd) = element.get_bmd(11, analysis_case) # loop through each station for (i, m) in enumerate(bmd): xi = xis[i] x = self.length * xi # check bending moment self.assertTrue(np.isclose(m, analytical_bmd(x), atol=1e-06)) # check max bending moment l0 = self.length m_max = self.q * l0 * l0 / 8 # check value self.assertTrue(np.isclose(abs(m_max), max(np.abs(bmd)), atol=1e-06)) # check position self.assertTrue(np.isclose(0.5, xis[np.abs(bmd).argmax()], atol=1e-06)) # check shear force def analytical_sfd(x): return self.q * (x - self.length / 2) # get sfd (xis, sfd) = element.get_sfd(11, analysis_case) # loop through each station for (i, sf) in enumerate(sfd): xi = xis[i] x = self.length * xi # check shear force self.assertTrue(np.isclose(sf, analytical_sfd(x), atol=1e-06))
def __init__(self, buildProp, stiff_red = 0): """Inits the class, setting up calculation model :param buildProp: full scale properties of the building :type buildProp: :class:`~modelProp.buildProp` """ # Setting up calculation model # ------------ # preprocessor # --------- # constants & lists self.L = buildProp.H # length of the beam [m] self.n = buildProp.nz # no of nodes [-] self.z = buildProp.z_lev # coordinates [m] # everything starts with the analysis object self.analysis = FrameAnalysis2D() ### NODES # ------------- # Coordinates for geometrie self.node_coords_geom = [] for i in range(buildProp.nF+1): node = i * buildProp.hL self.node_coords_geom.append(node) # Sort from bottom to top of building, # must be done for inserting loads at right order! self.node_coords_geom = sorted(self.node_coords_geom, reverse=True) self.node_coords_load = [] for i in range(buildProp.nz): node = round(buildProp.z_lev[i], 1) self.node_coords_load.append(node) # Sort from bottom to top of building, # must be done for inserting loads at right order! self.node_coords_load = sorted(self.node_coords_load, reverse=True) # Merge / sort / remove duplicate nodes self.node_coords = sorted(list(set(self.node_coords_geom + self.node_coords_load)), reverse=True) # Insert nodes self.nodes = [] for i in range(len(self.node_coords)): node = self.analysis.create_node(coords=[0, self.node_coords[i]]) self.nodes.append(node) ## BEAMS # ------------- self.beams = [] # Counter for stiffness reduction j = -1 # Determine coords. where reductions shall be made hModule = buildProp.H / buildProp.nM # Reset wall mass to 0 buildProp.M_DL_CWall = 0 buildProp.recalcBuildMass() # Remark: Reverse node order here, going from bottom to tip for i in range(1, len(self.nodes)): #! n+1 (support, tip) # Get z-coord of current node z_i = self.nodes[-i].y # Raise counter if next module for reduction is reached if z_i % hModule == 0: j = j + 1 # Recalculate dist. mass # For concrete walls: mue_walls = A_walls [m2] * 2.5 [t/m3] if buildProp.structSys == 'concreteCore': mue_DL_CWall= ((buildProp.bCore + buildProp.t)**2 - (buildProp.bCore - buildProp.t)**2) * 2.5 mue_SLS_Tot = buildProp.M_SLS_Tot / buildProp.H + (1 - stiff_red) ** j * mue_DL_CWall # Add mass of walls to total mass buildProp.M_DL_CWall += (1 - stiff_red) ** j * mue_DL_CWall * (self.nodes[-i-1].y - self.nodes[-i].y) else: raise('No structural system specified') ## MATERIAL # ------------- self.material = Material("Dummy", buildProp.E, 0.3, mue_SLS_Tot, colour='w') ## SECTION # ------------- if buildProp.structSys == 'concreteCore': I = buildProp.I * (1 - stiff_red) ** j else: raise('No structural system specified') self.section = Section(area=1, ixx=I) # Add beams beam = self.analysis.create_element( el_type='EB2-2D', nodes=[self.nodes[-i], self.nodes[-i-1]], material=self.material, section=self.section) self.beams.append(beam) # Print stiffness distribution for control # print('at z = ' + str(self.nodes[-i].y)) # print('I = ' + str(beam.section.ixx)) # Recalculate the building mass, now with walls buildProp.recalcBuildMass() # boundary conditions are objects self.freedom_case = cases.FreedomCase() self.freedom_case.add_nodal_support(node=self.nodes[-1], val=0, dof=0) self.freedom_case.add_nodal_support(node=self.nodes[-1], val=0, dof=1) self.freedom_case.add_nodal_support(node=self.nodes[-1], val=0, dof=5)
def calcMeanDeflection(self, fname, F_p_j, H_fs, E, I, nz, z_lev_fs): # Setting up static calculation # ------------ # preprocessor # --------- # constants & lists L = H_fs # length of the beam [m] n = nz # no of nodes [-] z = np.append(L, z_lev_fs) # coordinates [m], append top of building z = np.append(z, 0) # coordinates [m], append support node # everything starts with the analysis object analysis = FrameAnalysis2D() # materials and sections are objects mat_dummy = Material("Dummy", E, 0.3, 1, colour='w') section = Section(area=1, ixx=I) # nodes are objects nodes = [] for i in range(0,n+2): #! n+2 (support, tip) node = analysis.create_node(coords=[0, z[i]]) nodes.append(node) # and so are beams! beams = [] for i in range(0,n+1): #! n+1 (support, tip) beam = analysis.create_element( el_type='EB2-2D', nodes=[nodes[i], nodes[i+1]], material=mat_dummy, section=section) beams.append(beam) # boundary conditions are objects freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=0) freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=1) freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=5) # so are loads! load_case = cases.LoadCase() for i in range(n): F_p = np.mean(F_p_j[i]) #[in KN] load_case.add_nodal_load(node=nodes[i+1], val=F_p , dof=0) # i+1 (support, tip) # an analysis case relates a support case to a load case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # ------ # solver # ------ # you can easily change the solver settings settings = SolverSettings() settings.linear_static.time_info = False # the linear static solver is an object and acts on the analysis object solver = LinearStatic(analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings) solver.solve() # ---- # post # ---- # there are plenty of post processing options! # analysis.post.plot_geom(analysis_case=analysis_case) # analysis.post.plot_geom(analysis_case=analysis_case, deformed=True, def_scale=1e2) # analysis.post.plot_frame_forces(analysis_case=analysis_case, shear=True) # analysis.post.plot_frame_forces(analysis_case=analysis_case, moment=True) # analysis.post.plot_reactions(analysis_case=analysis_case) # Support reactions, to check bending moment for validation for support in analysis_case.freedom_case.items: if support.dof in [5]: reaction = support.get_reaction(analysis_case=analysis_case) # read out deformation at top self.delta_p_mean = nodes[0].get_displacements(analysis_case)[0] writeToTxt(fname, "delta_p_mean: " + '{:02.3f}'.format(self.delta_p_mean))
def test_example5_7(self): l_a = np.sqrt(8000 * 8000 - 3000 * 3000) # create materials steel = Steel() # create 2d frame analysis object analysis = FrameAnalysis2D() section = Section(area=6e3, ixx=200e6) # create nodes node_a = analysis.create_node(coords=[0]) node_b = analysis.create_node(coords=[l_a, 3000]) node_c = analysis.create_node(coords=[l_a + 8000, 3000]) # create beam elements element_ab = analysis.create_element( el_type='EB2-2D', nodes=[node_a, node_b], material=steel, section=section ) element_bc = analysis.create_element( el_type='EB2-2D', nodes=[node_b, node_c], material=steel, section=section ) # add supports freedom_case = cases.FreedomCase() sup_a = [0, 0, 0] sup_a[0] = freedom_case.add_nodal_support(node=node_a, val=0, dof=0) sup_a[1] = freedom_case.add_nodal_support(node=node_a, val=0, dof=1) sup_a[2] = freedom_case.add_nodal_support(node=node_a, val=0, dof=5) sup_c = [0, 0, 0] sup_c[0] = freedom_case.add_nodal_support(node=node_c, val=0, dof=0) sup_c[1] = freedom_case.add_nodal_support(node=node_c, val=0, dof=1) sup_c[2] = freedom_case.add_nodal_support(node=node_c, val=0, dof=5) # add loads load_case = cases.LoadCase() load_case.add_nodal_load(node=node_b, val=50e3 * 3000 / 8000, dof=0) load_case.add_nodal_load(node=node_b, val=-50e3 * l_a / 8000, dof=1) load_case.add_element_load(element_bc.generate_udl(q=-4)) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check node displacement disp_b = node_b.get_displacements(analysis_case) u_b = disp_b[0] v_b = disp_b[1] r_b = disp_b[5] self.assertEqual(np.around(u_b, 4), 0.9950) self.assertEqual(np.around(v_b, 3), -4.982) self.assertEqual(np.around(r_b, 6), -0.000534) # check reactions ra_x = sup_a[0].get_reaction(analysis_case=analysis_case) ra_y = sup_a[1].get_reaction(analysis_case=analysis_case) ra_m = sup_a[2].get_reaction(analysis_case=analysis_case) rc_x = sup_c[0].get_reaction(analysis_case=analysis_case) rc_y = sup_c[1].get_reaction(analysis_case=analysis_case) rc_m = sup_c[2].get_reaction(analysis_case=analysis_case) self.assertEqual(np.around(ra_x/1e3, 1), 130.5) self.assertEqual(np.around(ra_y/1e3, 1), 55.7) self.assertEqual(np.around(ra_m/1e6, 2), 13.37) self.assertEqual(np.around(rc_x/1e3, 1), -149.3) self.assertEqual(np.around(rc_y/1e3, 1), 22.7) self.assertEqual(np.around(rc_m/1e6, 2), -45.36)
def test_example5_6(self): # create materials steel = Steel() # create 2d frame analysis object analysis = FrameAnalysis2D() section_ab = Section(area=6e3, ixx=200e6) section_bc = Section(area=4e3, ixx=50e6) # create nodes node_a = analysis.create_node(coords=[0]) node_b = analysis.create_node(coords=[8000]) node_p = analysis.create_node(coords=[10000]) node_c = analysis.create_node(coords=[13000]) # create beam elements element_ab = analysis.create_element( el_type='EB2-2D', nodes=[node_a, node_b], material=steel, section=section_ab ) element_bp = analysis.create_element( el_type='EB2-2D', nodes=[node_b, node_p], material=steel, section=section_bc ) element_pc = analysis.create_element( el_type='EB2-2D', nodes=[node_p, node_c], material=steel, section=section_bc ) # add supports freedom_case = cases.FreedomCase() sup_a = freedom_case.add_nodal_support(node=node_a, val=0, dof=1) sup_b = freedom_case.add_nodal_support(node=node_b, val=0, dof=1) sup_c = [0, 0, 0] sup_c[0] = freedom_case.add_nodal_support(node=node_c, val=0, dof=0) sup_c[1] = freedom_case.add_nodal_support(node=node_c, val=0, dof=1) sup_c[2] = freedom_case.add_nodal_support(node=node_c, val=0, dof=5) # add loads load_case = cases.LoadCase() load_case.add_element_load(element_ab.generate_udl(q=-2)) load_case.add_nodal_load(node=node_p, val=-20e3, dof=1) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check node displacement disp_a = node_a.get_displacements(analysis_case) disp_b = node_b.get_displacements(analysis_case) r_a = disp_a[5] r_b = disp_b[5] self.assertEqual(np.around(r_a, 7), -5.681e-4) self.assertEqual(np.around(r_b, 7), 0.696e-4) # check reactions ra_y = sup_a.get_reaction(analysis_case=analysis_case) rb_y = sup_b.get_reaction(analysis_case=analysis_case) rc_y = sup_c[1].get_reaction(analysis_case=analysis_case) rc_m = sup_c[2].get_reaction(analysis_case=analysis_case) self.assertEqual(np.around(ra_y/1e3, 2), 6.13) self.assertEqual(np.around(rb_y/1e3, 2), 23.00) self.assertEqual(np.around(rc_y/1e3, 2), 6.87) self.assertEqual(np.around(rc_m/1e6, 2), -9.32)
def test_example2_2(self): # create 2d frame analysis object analysis = FrameAnalysis2D() # create sections steel = Steel() section1 = Section(area=5000) section2 = Section(area=3000) # create nodes a = analysis.create_node(coords=[0, 0]) b = analysis.create_node(coords=[3000, 3000]) c = analysis.create_node(coords=[3000, -3000]) d = analysis.create_node(coords=[-3000/np.tan(np.pi/6), 3000]) e = analysis.create_node(coords=[-3000/np.tan(np.pi/6), -3000]) # create truss elements el1 = analysis.create_element( el_type='Bar2-2D', nodes=[e, a], material=steel, section=section1) el2 = analysis.create_element( el_type='Bar2-2D', nodes=[d, a], material=steel, section=section1) el3 = analysis.create_element( el_type='Bar2-2D', nodes=[b, a], material=steel, section=section2) el4 = analysis.create_element( el_type='Bar2-2D', nodes=[c, a], material=steel, section=section2) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=b, val=0, dof=0) freedom_case.add_nodal_support(node=b, val=0, dof=1) freedom_case.add_nodal_support(node=c, val=0, dof=0) freedom_case.add_nodal_support(node=c, val=0, dof=1) freedom_case.add_nodal_support(node=d, val=0, dof=0) freedom_case.add_nodal_support(node=d, val=0, dof=1) freedom_case.add_nodal_support(node=e, val=0, dof=0) freedom_case.add_nodal_support(node=e, val=0, dof=1) # add loads load_case = cases.LoadCase() load_case.add_nodal_load(node=a, val=1000e3, dof=0) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check node displacement disp_a = a.get_displacements(analysis_case) u = disp_a[0] v = disp_a[1] self.assertEqual(np.around(u, 2), 2.55) self.assertEqual(np.around(v, 2), 0) # check axial forces (_, n1) = el1.get_afd(n=1, analysis_case=analysis_case) (_, n2) = el2.get_afd(n=1, analysis_case=analysis_case) (_, n3) = el3.get_afd(n=1, analysis_case=analysis_case) (_, n4) = el4.get_afd(n=1, analysis_case=analysis_case) self.assertEqual(np.around(n1/1e3, 1), 368.8) self.assertEqual(np.around(n2/1e3, 1), 368.8) self.assertEqual(np.around(n3/1e3, 1), -255.5) self.assertEqual(np.around(n4/1e3, 1), -255.5)
def calcPeakDeflection(self, fname, F_r_std, H_fs, E, I, mue, nz, z_lev_fs): # Setting up dynamic calculation # ------------ # preprocessor # --------- # constants & lists L = H_fs # length of the beam [m] n = nz # no of nodes [-] z = np.append(L, z_lev_fs) # coordinates [m], append top of building z = np.append(z, 0) # coordinates [m], append support node num_modes = 1 # everything starts with the analysis object analysis = FrameAnalysis2D() # materials and sections are objects mat_dummy = Material("Dummy", E, 0.3, mue, colour='w') section = Section(area=1, ixx=I) # nodes are objects nodes = [] for i in range(0,n+2): #! n+2 (support, tip) node = analysis.create_node(coords=[0, z[i]]) nodes.append(node) # and so are beams! beams = [] for i in range(0,n+1): #! n+1 (support, tip) beam = analysis.create_element( el_type='EB2-2D', nodes=[nodes[i], nodes[i+1]], material=mat_dummy, section=section) beams.append(beam) # boundary conditions are objects freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=0) freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=1) freedom_case.add_nodal_support(node=nodes[-1], val=0, dof=5) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=cases.LoadCase()) # ---------------- # frequency solver # ---------------- settings = SolverSettings() settings.natural_frequency.time_info = True settings.natural_frequency.num_modes = num_modes solver = NaturalFrequency( analysis=analysis, analysis_cases=[analysis_case], solver_settings=settings) # Manual solver, see feastruct/solvers/naturalfrequency.py, in order # to extract mass/stiffness-matrix and eigenvectors # assign the global degree of freedom numbers solver.assign_dofs() # Get the global stiffness / mass matrix (K, Kg) = solver.assemble_stiff_matrix() M = solver.assemble_mass_matrix() # apply the boundary conditions K_mod = solver.remove_constrained_dofs(K=K, analysis_case=analysis_case) M_mod = solver.remove_constrained_dofs(K=M, analysis_case=analysis_case) # Solve for the eigenvalues (w, v) = solver.solve_eigenvalue(A=K_mod, M=M_mod, eigen_settings=settings.natural_frequency) # compute natural frequencies in Hz f = np.sqrt(w) / 2 / np.pi # Normalize Eigenvector v = v / v[0] * L # # Get only dof ux # u = np.zeros(n+1) # for i in range(0, n+1): # j = i * 3 # u[i] = v[j] # Get generalized quantities K_mod = K_mod.toarray() K_gen = np.dot(np.dot(v.T, K_mod), v) M_mod = M_mod.toarray() M_gen = np.dot(np.dot(v.T, M_mod), v) # To check, compute # f_k = np.sqrt(K_gen/M_gen) / 2 / np.pi # print(f/f_k) # K_gen = 3 * E * I /(L^3) / L K_gen = K_gen[0][0] # Calculate peak displacement delta_r_std = v[0][0] / K_gen * F_r_std g_peak = response.calcPeakFactor(self, 3600, f[0]) # Peak Factor delta_r_max = g_peak * delta_r_std writeToTxt(fname, "delta_r_std: " + '{:02.3f}'.format(delta_r_std)) writeToTxt(fname, "g_peak: " + '{:02.3f}'.format(g_peak)) writeToTxt(fname, "delta_r_max: " + '{:02.3f}'.format(delta_r_max))
def preprocessor(length, depth, panels, freq): w = 10 # load per unit length [N/mm] dx = length / panels # length of a truss panel # create 2d frame analysis object analysis = FrameAnalysis2D() # create materials and sections steel = Steel() section_deck = Section(area=3230, ixx=23.6e6) # 200UB25 section_vertical = Section(area=3000, ixx=3.91e6) # 100x9 SHS section_diagonal = Section(area=314) # 20 dia rod section_tie = Section(area=1018) # 36 dia rod # create deck nodes nodes_deck = [] for i in range(panels + 1): nodes_deck.append(analysis.create_node(coords=[i * dx])) # create tie nodes - first node coincides with first deck node nodes_tie = [nodes_deck[0]] for i in range(panels - 1): # fit parabola x = (i + 1) * dx y = 4 * depth / length / length * x * x - 4 * depth / length * x nodes_tie.append(analysis.create_node(coords=[x, y])) # last node coincides with last deck node nodes_tie.append(nodes_deck[-1]) # create deck (beam) elements elements_deck = [] for i in range(panels): elements_deck.append( analysis.create_element(el_type='EB2-2D', nodes=[nodes_deck[i], nodes_deck[i + 1]], material=steel, section=section_deck)) # create tie (bar) elements elements_tie = [] for i in range(panels): elements_tie.append( analysis.create_element(el_type='Bar2-2D', nodes=[nodes_tie[i], nodes_tie[i + 1]], material=steel, section=section_tie)) # create vertical (beam) elements elements_vertical = [] for i in range(panels - 1): elements_vertical.append( analysis.create_element( el_type='EB2-2D', nodes=[nodes_deck[i + 1], nodes_tie[i + 1]], material=steel, section=section_vertical)) # create diagonal (bar) elements elements_diaongal = [] for i in range(panels - 2): elements_diaongal.append( analysis.create_element( el_type='Bar2-2D', nodes=[nodes_deck[i + 1], nodes_tie[i + 2]], material=steel, section=section_diagonal)) elements_diaongal.append( analysis.create_element( el_type='Bar2-2D', nodes=[nodes_deck[i + 2], nodes_tie[i + 1]], material=steel, section=section_diagonal)) # add supports freedom_case = cases.FreedomCase() freedom_case.add_nodal_support(node=nodes_deck[0], val=0, dof=0) freedom_case.add_nodal_support(node=nodes_deck[0], val=0, dof=1) freedom_case.add_nodal_support(node=nodes_deck[-1], val=0, dof=1) # add loads load_case = cases.LoadCase() # if frequency analysis, don't bother adding load if not freq: for el in elements_deck: load_case.add_element_load(el.generate_udl(q=-w)) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) return (analysis, analysis_case)
def test_example4_15(self): # create materials steel = Material(name='steel_imperial', elastic_modulus=29e3, poissons_ratio=0.3, rho=0) # create 2d frame analysis object analysis = FrameAnalysis2D() analysis.post.n_subdiv = 3 beam = Section(ixx=128.5) # create nodes n = 20 # number of beam segments (must be an even number to ensure point load in centre) L = 300 # length k_L = 15 # spring length k = 1.5 # foundation modulus dx = L/n spring = Section(area=k*dx*k_L/29e3) beam_nodes = [] spring_nodes = [] # beam nodes for i in range(n+1): beam_nodes.append(analysis.create_node(coords=[i*L/n])) # spring nodes for i in range(n-1): spring_nodes.append(analysis.create_node(coords=[(i+1)*L/n, -k_L])) # create elements beam_elements = [] spring_elements = [] # create beam elements for i in range(n): beam_elements.append(analysis.create_element( el_type='EB2-2D', nodes=[beam_nodes[i], beam_nodes[i+1]], material=steel, section=beam )) # create spring elements for i in range(n-1): spring_elements.append(analysis.create_element( el_type='Bar2-2D', nodes=[beam_nodes[i+1], spring_nodes[i]], material=steel, section=spring )) # add supports freedom_case = cases.FreedomCase() spring_supports_x = [] spring_supports_y = [] # add end supports freedom_case.add_nodal_support(node=beam_nodes[0], val=0, dof=0) freedom_case.add_nodal_support(node=beam_nodes[0], val=0, dof=1) freedom_case.add_nodal_support(node=beam_nodes[-1], val=0, dof=1) # add spring support for spring_node in spring_nodes: spring_supports_x.append(freedom_case.add_nodal_support( node=spring_node, val=0, dof=0)) spring_supports_y.append(freedom_case.add_nodal_support( node=spring_node, val=0, dof=1)) # add loads load_case = cases.LoadCase() load_case.add_nodal_load(node=beam_nodes[int(n/2)], val=-40, dof=1) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check node displacement disp = beam_nodes[int(n/2)].get_displacements(analysis_case) v_p = disp[1] self.assertEqual(np.around(v_p, 3), -0.238) # check bending moments (_, m) = beam_elements[int(n/2)].get_bmd(n=2, analysis_case=analysis_case) self.assertEqual(np.around(m[0], 0), -547)
from feastruct.solvers.naturalfrequency import NaturalFrequency from feastruct.solvers.feasolve import SolverSettings # ------------ # preprocessor # ------------ # constants & lists n = 20 # number of elements (make even to ensure point load in centre) L = 10000 # length of arch h = 3000 # height of arch nodes = [] # list holding the node objects elements = [] # list holding the element objects # create 2d frame analysis object analysis = FrameAnalysis2D() # create materials and sections steel = Steel() section = Section(area=3230, ixx=23.6e6) # create nodes for i in range(n + 1): x = i * L / n y = h * np.sin(np.pi * x / L) nodes.append(analysis.create_node(coords=[x, y])) # create beam elements for i in range(n): elements.append( analysis.create_element(el_type='EB2-2D',
def test_example3_3(self): nodes = [] # list holding the node objects elements = [] # list holding the element objects # create 2d frame analysis object analysis = FrameAnalysis2D() # create sections steel = Steel() section1 = Section(area=15e3) section2 = Section(area=18e3) section3 = Section(area=20e3) # create nodes nodes.append(analysis.create_node(coords=[0, 0])) nodes.append(analysis.create_node(coords=[4000/np.tan(np.pi/6), 4000])) nodes.append(analysis.create_node(coords=[4000/np.tan(np.pi/6) + 4000, 0])) nodes.append(analysis.create_node(coords=[0, 4000])) # create truss elements elements.append(analysis.create_element( el_type='Bar2-2D', nodes=[nodes[0], nodes[1]], material=steel, section=section1 )) elements.append(analysis.create_element( el_type='Bar2-2D', nodes=[nodes[1], nodes[2]], material=steel, section=section3 )) elements.append(analysis.create_element( el_type='Bar2-2D', nodes=[nodes[0], nodes[2]], material=steel, section=section2 )) elements.append(analysis.create_element( el_type='Bar2-2D', nodes=[nodes[3], nodes[1]], material=steel, section=section3 )) # add supports freedom_case = cases.FreedomCase() sup1 = freedom_case.add_nodal_support(node=nodes[0], val=0, dof=0) sup2 = freedom_case.add_nodal_support(node=nodes[0], val=0, dof=1) sup3 = freedom_case.add_nodal_support(node=nodes[2], val=0, dof=1) sup4 = freedom_case.add_nodal_support(node=nodes[3], val=0, dof=0) sup5 = freedom_case.add_nodal_support(node=nodes[3], val=0, dof=1) # add loads load_case = cases.LoadCase() load_case.add_nodal_load(node=nodes[1], val=500e3*np.cos(2*np.pi/9), dof=0) load_case.add_nodal_load(node=nodes[1], val=500e3*np.sin(2*np.pi/9), dof=1) # add analysis case analysis_case = cases.AnalysisCase(freedom_case=freedom_case, load_case=load_case) # linear static solver LinearStatic(analysis=analysis, analysis_cases=[analysis_case]).solve() # check node displacement disp_a = nodes[1].get_displacements(analysis_case) disp_b = nodes[2].get_displacements(analysis_case) u_a = disp_a[0] v_a = disp_a[1] u_b = disp_b[0] self.assertEqual(np.around(u_a, 2), 0.38) self.assertEqual(np.around(v_a, 2), 1.23) self.assertEqual(np.around(u_b, 2), -0.44) # check reactions rc_x = sup1.get_reaction(analysis_case=analysis_case) rc_y = sup2.get_reaction(analysis_case=analysis_case) rb_y = sup3.get_reaction(analysis_case=analysis_case) rd_x = sup4.get_reaction(analysis_case=analysis_case) rd_y = sup5.get_reaction(analysis_case=analysis_case) self.assertEqual(np.around(rc_x/1e3, 1), -162.5) self.assertEqual(np.around(rc_y/1e3, 1), -177.1) self.assertEqual(np.around(rb_y/1e3, 1), -144.3) self.assertEqual(np.around(rd_x/1e3, 1), -220.5) self.assertEqual(np.around(rd_y/1e3, 1), 0)