In [1]:
import salib as sl
import numpy as np
from MemberLoads import EF
In [2]:
class Member(object):
RELEASES = {'MZJ':2, 'MZK':5}
E = 200000.
G = 77000.
def __init__(self,ident,nodej,nodek):
self.id = ident
self.nodej = nodej
self.nodek = nodek
self.dcx,self.dcy,self.L = nodej.to(nodek)
self.KL = None # stiffness matrix, local coords
self.KG = None # stiffness matrix, global coords
self.releases = set()
self.Ix = None
self.A = None
self.Tm = None # transformation matrix, global to local
##self.fefsl = None # fixed end forces, local coordinates
##self.mefs = None # member end forces, local coordinates
def add_release(self,rel):
r = rel.upper()
if r not in self.RELEASES:
raise Exception('Invalid release name: {}'.format(rel))
self.releases.add(r)
def __repr__(self):
return '{}("{}","{}","{}")'.format(self.__class__.__name__,self.id,self.nodej,self.nodek)
def localK(self):
"""Return the member stiffness matrix in local coordinates"""
L = self.L
E = self.E
A = self.A
I = self.Ix
k0 = E*A/L
k12 = 12.*E*I/L**3
k6 = 6.*E*I/L**2
k4 = 4.*E*I/L
k2 = 2.*E*I/L
KL = np.mat([[ k0, 0, 0, -k0, 0, 0],
[ 0, k12, k6, 0, -k12, k6],
[ 0, k6, k4, 0, -k6, k2],
[-k0, 0, 0, k0, 0, 0],
[ 0, -k12, -k6, 0, k12, -k6],
[ 0, k6, k2, 0, -k6, k4]])
for r in self.releases:
KL = self.releaseK(KL,self.RELEASES[r])
self.Kl = KL
return KL
def releaseK(self,Kl,rel):
"""Return a modified stiffness matrix to account for a moment release
at one of the ends. Kl is the original matrix, dx, dy are projections of the
member, and 'rel' is 2 or 5 to identify the local dof # of the released dof.
Both KL and KG are returned if the transformation matrix, T, is provided"""
L = self.L
if rel == 2:
if Kl[5,5] == 0.: # is other end also pinned?
em = np.mat([1.,0.]).T # corrective end moments, far end pinned
else:
em = np.mat([1.,0.5]).T # corrective end moments, far end fixed
elif rel == 5:
if Kl[2,2] == 0.:
em = np.mat([0.,1.]).T
else:
em = np.mat([0.5,1.]).T
else:
raise ValueError("Invalid release #: {}".format(rel))
Tf = np.mat([[0.,0.],[1./L,1./L],[1.,0.],[0.,0.],[-1./L,-1./L],[0.,1.]])
M = Tf*em
K = Kl.copy()
K[:,1] -= M*K[rel,1] # col 1 - forces for unit vertical displacment at j-end
K[:,2] -= M*K[rel,2] # col 2 - forces for unit rotation at j-end
K[:,4] -= M*K[rel,4] # col 4 - forces for unit vertical displacment at k-end
K[:,5] -= M*K[rel,5] # col 5 - forces for unit rotation at k-end
return K
def transform(self):
"""Return a transformation matrix to transform forces and displacements
in global coordinates to local coordinates for the 2-d frame member.
This is called the member transformation matrix, Tm"""
cx = self.dcx
cy = self.dcy
self.Tm = np.mat([[ cx, cy, 0, 0, 0, 0],
[-cy, cx, 0, 0, 0, 0],
[ 0, 0, 1, 0, 0, 0],
[ 0, 0, 0, cx, cy, 0],
[ 0, 0, 0, -cy, cx, 0],
[ 0, 0, 0, 0, 0, 1]])
return self.Tm
def fefs(self,loads_factors):
fef = sum([l.fefs()*f for l,f in loads_factors],EF())
if loads_factors:
for r in self.releases:
fef = self.releaseFEF(fef,self.RELEASES[r])
return fef
def vm(self,loads,mefs=None):
"""Return shear and moment 'diagrams'. Return (xv,v,xm,m) -
xv and xm are positions along span, and v and m are shears and
moments at those points. Use normal sign convention (not beam sign
convention) - on left FBD, moments +ive CCW, shear +ive upwards.
"""
def _getx(self,loads,attr):
degree = 0
pts = [0.,self.L]
for load in loads:
pt1,pt2,d = getattr(load,attr)
for p in pt1,pt2:
if p is not None:
pts.append(p)
if d > degree:
degree = d
ptsv = np.array(pts)
if degree > 1:
ptsv = np.concatenate((ptsv,np.linspace(0,self.L)))
ptsv.sort()
return np.unique(ptsv)
xv = _getx(self,loads,'vpts')
xm = _getx(self,loads,'mpts')
return xv,None,xm,None
def releaseFEF(self,mef,rel):
"""Return a modified fixed end force vector to account for a moment release
at one of the ends. mef is the original member end force, 'rel' is 2 or 5 to identify
the local dof # of the released moment."""
fef = mef.fefs
L = self.L
if rel == 2:
if fef[5,0] == 0.: # is other end also pinned?
em = np.mat([1.,0.]).T # corrective end moments, far end pinned
else:
em = np.mat([1.,0.5]).T # corrective end moments, far end fixed
elif rel == 5:
if fef[2,0] == 0.:
em = np.mat([0.,1.]).T
else:
em = np.mat([0.5,1.]).T
else:
raise ValueError("Invalid release #: {}".format(rel))
Tf = np.mat([[0.,0.],[1./L,1./L],[1.,0.],[0.,0.],[-1./L,-1./L],[0.,1.]])
M = Tf*em
return EF(fef - M*fef[rel])
In [ ]: