def pop_k(beam_props): # beam_props is a dictionary with the following values # xn1 : position vector for start node # xn2 : position vector for end node # Le : Effective beam length (taking into account node diameter) # Asy : Effective area for shear effects, y direction # Asz : Effective area for shear effects, z direction # G : Shear modulus # E : Elastic modulus # J : Polar moment of inertia # Iy : Bending moment of inertia, y direction # Iz : bending moment of inertia, z direction # p : The roll angle (radians) # T : internal element end force # shear : whether shear effects are considered. xn1 = beam_props["xn1"] xn2 = beam_props["xn2"] L = beam_props["Le"] Le = beam_props["Le"] Ax = beam_props["Ax"] Asy = beam_props["Asy"] Asz = beam_props["Asz"] G = beam_props["G"] E = beam_props["E"] J = beam_props["J"] Iy = beam_props["Iy"] Iz = beam_props["Iz"] p = beam_props["p"] T = beam_props["T"] shear = beam_props["shear"] t = pfeautil.coord_trans(xn1,xn2,Le,p) if shear: Ksy = 12.0*E*Iz / (G*Asy*Le*Le) Ksz = 12.0*E*Iy / (G*Asz*Le*Le) Dsy = (1+Ksy)*(1+Ksy) Dsz = (1+Ksz)*(1+Ksz) else: Ksy = Ksz = 0.0 Dsy = Dsz = 1.0 data = np.zeros(30) rows = np.array([0,1,2,3,4,5,5,4,2,1]) cols = np.array([0,1,2,3,4,5,1,2,4,5]) return data,rows,cols
def assemble_loads(loads,constraints,nodes, beam_sets,global_args,tot_dof,length_scaling): # creates force vector b # Nodal Loads # virtual loads from prescribed displacements forces = co.matrix(0.0,(tot_dof,1))#np.zeros(tot_dof) dP = co.matrix(0.0,(tot_dof,1))#np.zeros(tot_dof) grav = np.array(global_args["gravity"]) #Loads from specified nodal loads for load in loads: forces[6*load['node']+load['DOF']] = load['value'] if np.linalg.norm(grav) > 0: for beamset,args in beam_sets: rho = args["rho"] node_mass = args["node_mass"] Ax = args["Ax"] L = args["Le"] for beam in beamset: t = pfeautil.coord_trans(nodes[beam[0]],nodes[beam[1]],L,args["roll"]) tq = t[3:6] tr = t[6:9] mom = np.cross(np.cross(tq,tr),grav) forces[6*beam[0]+0] += (0.5*rho*Ax*L+node_mass)*grav[0] forces[6*beam[0]+1] += (0.5*rho*Ax*L+node_mass)*grav[1] forces[6*beam[0]+2] += (0.5*rho*Ax*L+node_mass)*grav[2] forces[6*beam[1]+0] += (0.5*rho*Ax*L+node_mass)*grav[0] forces[6*beam[1]+1] += (0.5*rho*Ax*L+node_mass)*grav[1] forces[6*beam[1]+2] += (0.5*rho*Ax*L+node_mass)*grav[2] forces[6*beam[0]+3] += ( 1.0/12.0*rho*Ax*L*L)*mom[0] forces[6*beam[0]+4] += ( 1.0/12.0*rho*Ax*L*L)*mom[1] forces[6*beam[0]+5] += ( 1.0/12.0*rho*Ax*L*L)*mom[2] forces[6*beam[1]+3] += (-1.0/12.0*rho*Ax*L*L)*mom[0] forces[6*beam[1]+4] += (-1.0/12.0*rho*Ax*L*L)*mom[1] forces[6*beam[1]+5] += (-1.0/12.0*rho*Ax*L*L)*mom[2] for constraint in constraints: dP[int(6*constraint['node']+constraint['DOF'])] = constraint['value']*length_scaling return forces,dP
def frame_element_force(s,beam_props): # beam_props is a dictionary with the following values # xn1 : position vector for start node # xn2 : position vector for end node # Le : Effective beam length (taking into account node diameter) # Asy : Effective area for shear effects, y direction # Asz : Effective area for shear effects, z direction # G : Shear modulus # E : Elastic modulus # J : Polar moment of inertia # Iy : Bending moment of inertia, y direction # Iz : bending moment of inertia, z direction # p : The roll angle (radians) # T : internal element end force # shear : whether shear effects are considered. xn1 = beam_props["xn1"] xn2 = beam_props["xn2"] dn1 = beam_props["dn1"] dn2 = beam_props["dn2"] L = beam_props["Le"] Le = beam_props["Le"] Ax = beam_props["Ax"] Asy = beam_props["Asy"] Asz = beam_props["Asz"] G = beam_props["G"] E = beam_props["E"] J = beam_props["J"] Iy = beam_props["Iy"] Iz = beam_props["Iz"] p = beam_props["p"] shear = beam_props["shear"] f = np.zeros(12) t = pfeautil.coord_trans(xn1,xn2,Le,p) if shear: Ksy = 12.*E*Iz / (G*Asy*Le*Le) Ksz = 12.*E*Iy / (G*Asz*Le*Le) Dsy = (1+Ksy)*(1+Ksy) Dsz = (1+Ksz)*(1+Ksz) else: Ksy = Ksz = 0.0 Dsy = Dsz = 1.0 del1 = np.dot(dn2[0:3]-dn1[0:3],t[0:3]) # (d7-d1)*t1 + (d8-d2)*t2 + (d9-d3)*t3 II del2 = np.dot(dn2[0:3]-dn1[0:3],t[3:6]) # (d7-d1)*t4 + (d8-d2)*t5 + (d9-d3)*t6 III del3 = np.dot(dn2[0:3]-dn1[0:3],t[6:9]) # (d7-d1)*t7 + (d8-d2)*t8 + (d9-d3)*t9 III # del4 = np.dot(dn2[3:6]+dn1[3:6],t[0:3]) # (d4+d10)*t1 + (d5+d11)*t2 + (d6+d12)*t3 del5 = np.dot(dn2[3:6]+dn1[3:6],t[3:6]) # (d4+d10)*t4 + (d5+d11)*t5 + (d6+d12)*t6 I del6 = np.dot(dn2[3:6]+dn1[3:6],t[6:9]) # (d4+d10)*t7 + (d5+d11)*t8 + (d6+d12)*t9 I del7 = np.dot(dn2[3:6]-dn1[3:6],t[0:3]) # (d10-d4)*t1 + (d11-d5)*t2 + (d12-d6)*t3 # del8 = np.dot(dn2[3:6]-dn1[3:6],t[3:6]) # (d10-d4)*t4 + (d11-d5)*t5 + (d12-d6)*t6 # del9 = np.dot(dn2[3:6]-dn1[3:6],t[6:9]) # (d10-d4)*t7 + (d11-d5)*t8 + (d12-d6)*t9 # del10 = np.dot(dn1[3:6],t[0:3]) # d4 *t1 + d5 *t2 + d6 *t3 del11 = np.dot(dn1[3:6],t[3:6]) # d4 *t4 + d5 *t5 + d6 *t6 del12 = np.dot(dn1[3:6],t[6:9]) # d4 *t7 + d5 *t8 + d6 *t9 # del13 = np.dot(dn2[3:6],t[0:3]) # d10*t1 + d11*t2 + d12*t3 del14 = np.dot(dn2[3:6],t[3:6]) # d10*t4 + d11*t5 + d12*t6 del15 = np.dot(dn2[3:6],t[6:9]) # d10*t7 + d11*t8 + d12*t9 axial_strain = del1 / Le #Axial force component s[0] = -(Ax*E/Le)*del1 T = -s[0] #if geom: #T = -s[1] #Shear forces # positive Vy in local y direction s[1] = -1.0*del2*(12.*E*Iz/(Le*Le*Le*(1.+Ksy)) + T/L*(1.2+2.0*Ksy+Ksy*Ksy)/Dsy) + \ del6*( 6.*E*Iz/(Le*Le*(1.+Ksy)) + T/10.0/Dsy) # positive Vz in local z direction s[2] = -1.0*del3*(12.*E*Iy/(Le*Le*Le*(1.+Ksz)) + T/L*(1.2+2.0*Ksz+Ksz*Ksz)/Dsz) - \ del5*( 6.*E*Iy/(Le*Le*(1.+Ksz)) + T/10.0/Dsz) #Torsion Forces # positive Tx r.h.r. about local x axis s[3] = -1.0*del7*(G*J/Le) #Bending Forces #positive My -> positive x-z curvature s[4] = 1.0*del3*( 6.*E*Iy/(Le*Le*(1.+Ksz)) + T/10.0/Dsz) + \ del11*((4.+Ksz)*E*Iy/(Le*(1.+Ksz)) + T*L*(2.0/15.0+Ksz/6.0+Ksz*Ksz/12.0)/Dsz ) + \ del14*((2.-Ksz)*E*Iy/(Le*(1.+Ksz)) - T*L*(1.0/30.0+Ksz/6.0+Ksz*Ksz/12.0)/Dsz ) #positive Mz -> positive x-y curvature s[5] = -1.0*del2*( 6.*E*Iz/(Le*Le*(1.+Ksy)) + T/10.0/Dsy) + \ del12*((4.+Ksy)*E*Iz/(Le*(1.+Ksy)) + T*L*(2.0/15.0+Ksy/6.0+Ksy*Ksy/12.0)/Dsy ) + \ del15*((2.-Ksy)*E*Iz/(Le*(1.+Ksy)) - T*L*(1.0/30.0+Ksy/6.0+Ksy*Ksy/12.0)/Dsy ) s[6] = -s[0]; s[7] = -s[1]; s[8] = -s[2]; s[9] = -s[3]; s[10] = 1.0*del3*( 6.*E*Iy/(Le*Le*(1.+Ksz)) + T/10.0/Dsz ) + \ del14*((4.+Ksz)*E*Iy/(Le*(1.+Ksz)) + T*L*(2.0/15.0+Ksz/6.0+Ksz*Ksz/12.0)/Dsz ) + \ del11*((2.-Ksz)*E*Iy/(Le*(1.+Ksz)) - T*L*(1.0/30.0+Ksz/6.0+Ksz*Ksz/12.0)/Dsz ) s[11] = -1.0*del2*( 6.*E*Iz/(Le*Le*(1.+Ksy)) + T/10.0/Dsy ) + \ del15*((4.+Ksy)*E*Iz/(Le*(1.+Ksy)) + T*L*(2.0/15.0+Ksy/6.0+Ksy*Ksy/12.0)/Dsy ) + \ del12*((2.-Ksy)*E*Iz/(Le*(1.+Ksy)) - T*L*(1.0/30.0+Ksy/6.0+Ksy*Ksy/12.0)/Dsy )
def geometric_K(beam_props): # beam_props is a dictionary with the following values # xn1 : position vector for start node # xn2 : position vector for end node # Le : Effective beam length (taking into account node diameter) # Asy : Effective area for shear effects, y direction # Asz : Effective area for shear effects, z direction # G : Shear modulus # E : Elastic modulus # J : Polar moment of inertia # Iy : Bending moment of inertia, y direction # Iz : bending moment of inertia, z direction # p : The roll angle (radians) # T : internal element end force # shear : whether shear effects are considered. xn1 = beam_props["xn1"] xn2 = beam_props["xn2"] L = beam_props["Le"] Le = beam_props["Le"] Ax = beam_props["Ax"] Asy = beam_props["Asy"] Asz = beam_props["Asz"] G = beam_props["G"] E = beam_props["E"] J = beam_props["J"] Iy = beam_props["Iy"] Iz = beam_props["Iz"] p = beam_props["p"] T = beam_props["T"] shear = beam_props["shear"] #initialize the geometric stiffness matrix kg = np.zeros((12,12)) t = pfeautil.coord_trans(xn1,xn2,Le,p) if shear: Ksy = 12.0*E*Iz / (G*Asy*Le*Le); Ksz = 12.0*E*Iy / (G*Asz*Le*Le); Dsy = (1+Ksy)*(1+Ksy); Dsz = (1+Ksz)*(1+Ksz); else: Ksy = Ksz = 0.0; Dsy = Dsz = 1.0; #print(T) kg[0][0] = kg[6][6] = 0.0 # T/L kg[1][1] = kg[7][7] = T/L*(1.2+2.0*Ksy+Ksy*Ksy)/Dsy kg[2][2] = kg[8][8] = T/L*(1.2+2.0*Ksz+Ksz*Ksz)/Dsz kg[3][3] = kg[9][9] = T/L*J/Ax kg[4][4] = kg[10][10] = T*L*(2.0/15.0+Ksz/6.0+Ksz*Ksz/12.0)/Dsz kg[5][5] = kg[11][11] = T*L*(2.0/15.0+Ksy/6.0+Ksy*Ksy/12.0)/Dsy kg[0][6] = kg[6][0] = 0.0 # -T/L kg[4][2] = kg[2][4] = kg[10][2] = kg[2][10] = -T/10.0/Dsz kg[8][4] = kg[4][8] = kg[10][8] = kg[8][10] = T/10.0/Dsz kg[5][1] = kg[1][5] = kg[11][1] = kg[1][11] = T/10.0/Dsy kg[7][5] = kg[5][7] = kg[11][7] = kg[7][11] = -T/10.0/Dsy kg[3][9] = kg[9][3] = -kg[3][3] kg[7][1] = kg[1][7] = -T/L*(1.2+2.0*Ksy+Ksy*Ksy)/Dsy kg[8][2] = kg[2][8] = -T/L*(1.2+2.0*Ksz+Ksz*Ksz)/Dsz kg[10][4] = kg[4][10] = -T*L*(1.0/30.0+Ksz/6.0+Ksz*Ksz/12.0)/Dsz kg[11][5] = kg[5][11] = -T*L*(1.0/30.0+Ksy/6.0+Ksy*Ksy/12.0)/Dsy #now we transform kg to the global coordinates kg = pfeautil.atma(t,kg) # Check and enforce symmetry of the elastic stiffness matrix for the element kg = 0.5*(kg+kg.T) return [kg[:6,:6],kg[6:,:6],kg[:6,6:],kg[6:,6:]]
def elastic_K(beam_props): # beam_props is a dictionary with the following values # xn1 : position vector for start node # xn2 : position vector for end node # Le : Effective beam length (taking into account node diameter) # Asy : Effective area for shear effects, y direction # Asz : Effective area for shear effects, z direction # G : Shear modulus # E : Elastic modulus # J : Polar moment of inertia # Iy : Bending moment of inertia, y direction # Iz : bending moment of inertia, z direction # p : The roll angle (radians) # T : internal element end force # shear : Do we consider shear effects #Start by importing the beam properties xn1 = beam_props["xn1"] xn2 = beam_props["xn2"] Le = beam_props["Le"] Ax = beam_props["Ax"] Asy = beam_props["Asy"] Asz = beam_props["Asz"] G = beam_props["G"] E = beam_props["E"] J = beam_props["J"] Iy = beam_props["Iy"] Iz = beam_props["Iz"] p = beam_props["p"] shear = beam_props["shear"] #initialize the output k = np.zeros((12,12)) #k = co.matrix(0.0,(12,12)) #define the transform between local and global coordinate frames t = pfeautil.coord_trans(xn1,xn2,Le,p) #calculate Shear deformation effects Ksy = 0 Ksz = 0 #begin populating that elastic stiffness matrix if shear: Ksy = 12.0*E*Iz / (G*Asy*Le*Le) Ksz = 12.0*E*Iy / (G*Asz*Le*Le) else: Ksy = Ksz = 0.0 k[0,0] = k[6,6] = 1.0*E*Ax / Le k[1,1] = k[7,7] = 12.*E*Iz / ( Le*Le*Le*(1.+Ksy) ) k[2,2] = k[8,8] = 12.*E*Iy / ( Le*Le*Le*(1.+Ksz) ) k[3,3] = k[9,9] = 1.0*G*J / Le k[4,4] = k[10,10] = (4.+Ksz)*E*Iy / ( Le*(1.+Ksz) ) k[5,5] = k[11,11] = (4.+Ksy)*E*Iz / ( Le*(1.+Ksy) ) k[4,2] = k[2,4] = -6.*E*Iy / ( Le*Le*(1.+Ksz) ) k[5,1] = k[1,5] = 6.*E*Iz / ( Le*Le*(1.+Ksy) ) k[6,0] = k[0,6] = -k[0,0] k[11,7] = k[7,11] = k[7,5] = k[5,7] = -k[5,1] k[10,8] = k[8,10] = k[8,4] = k[4,8] = -k[4,2] k[9,3] = k[3,9] = -k[3,3] k[10,2] = k[2,10] = k[4,2] k[11,1] = k[1,11] = k[5,1] k[7,1] = k[1,7] = -k[1,1] k[8,2] = k[2,8] = -k[2,2] k[10,4] = k[4,10] = (2.-Ksz)*E*Iy / ( Le*(1.+Ksz) ) k[11,5] = k[5,11] = (2.-Ksy)*E*Iz / ( Le*(1.+Ksy) ) #now we transform k to the global coordinates k = pfeautil.atma(t,k) # Check and enforce symmetry of the elastic stiffness matrix for the element k = 0.5*(k+k.T) ''' for i in range(12): for j in range(i+1,12): if(k[i][j]!=k[j][i]): if(abs(1.0*k[i][j]/k[j][i]-1.0) > 1.0e-6 and (abs(1.0*k[i][j]/k[i][i]) > 1e-6 or abs(1.0*k[j][i]/k[i][i]) > 1e-6)): print("Ke Not Symmetric") k[i][j] = k[j][i] = 0.5 * ( k[i][j] + k[j][i] ) ''' return [k[:6,:6],k[6:,:6],k[:6,6:],k[6:,6:]]