Milestone 1 - input of nodes, members, loads and load combos.
This program performs an elastic analysis of 2-dimensional structural frames. It has the following features:
In [1]:
from __future__ import print_function
In [2]:
import salib as sl
sl.import_notebooks()
from Tables import Table
from Nodes import Node
from Members import Member
from LoadSets import LoadSet, LoadCombination
from NodeLoads import makeNodeLoad
from FixedEndForces import makeMemberLoad
from collections import OrderedDict, defaultdict
In [3]:
class Object(object):
pass
class Frame2D(object):
def __init__(self,dsname=None):
self.dsname = dsname
self.rawdata = Object()
self.nodes = OrderedDict()
self.members = OrderedDict()
self.nodeloads = LoadSet()
self.memberloads = LoadSet()
self.loadcombinations = LoadCombination()
#self.dofdesc = []
#self.nodeloads = defaultdict(list)
#self.membloads = defaultdict(list)
self.ndof = 0
self.nfree = 0
self.ncons = 0
self.R = None
self.D = None
self.PDF = None # P-Delta forces
COLUMNS_xxx = [] # list of column names for table 'xxx'
def get_table(self,tablename,extrasok=False):
columns = getattr(self,'COLUMNS_'+tablename)
t = Table(tablename,columns=columns)
t.read()
reqdl= columns
reqd = set(reqdl)
prov = set(t.columns)
if reqd-prov:
raise Exception('Columns missing {} for table "{}". Required columns are: {}'\
.format(list(reqd-prov),tablename,reqdl))
if not extrasok:
if prov-reqd:
raise Exception('Extra columns {} for table "{}". Required columns are: {}'\
.format(list(prov-reqd),tablename,reqdl))
return t
In [4]:
%%Table nodes
NODEID,X,Y,Z
A,0,0,5000
B,0,4000,5000
C,8000,4000,5000
D,8000,0,5000
In [5]:
@sl.extend(Frame2D)
class Frame2D:
COLUMNS_nodes = ('NODEID','X','Y')
def install_nodes(self):
node_table = self.get_table('nodes')
for ix,r in node_table.data.iterrows():
if r.NODEID in self.nodes:
raise Exception('Multiply defined node: {}'.format(r.NODEID))
n = Node(r.NODEID,r.X,r.Y)
self.nodes[n.id] = n
self.rawdata.nodes = node_table
def get_node(self,id):
try:
return self.nodes[id]
except KeyError:
raise Exception('Node not defined: {}'.format(id))
In [6]:
##test:
f = Frame2D()
In [7]:
##test:
f.install_nodes()
In [8]:
##test:
f.nodes
Out[8]:
In [9]:
##test:
f.get_node('C')
Out[9]:
In [10]:
%%Table members
MEMBERID,NODEJ,NODEK
AB,A,B
BC,B,C
DC,D,C
In [11]:
@sl.extend(Frame2D)
class Frame2D:
COLUMNS_members = ('MEMBERID','NODEJ','NODEK')
def install_members(self):
table = self.get_table('members')
for ix,m in table.data.iterrows():
if m.MEMBERID in self.members:
raise Exception('Multiply defined member: {}'.format(m.MEMBERID))
memb = Member(m.MEMBERID,self.get_node(m.NODEJ),self.get_node(m.NODEK))
self.members[memb.id] = memb
self.rawdata.members = table
def get_member(self,id):
try:
return self.members[id]
except KeyError:
raise Exception('Member not defined: {}'.format(id))
In [12]:
##test:
f.install_members()
f.members
Out[12]:
In [13]:
##test:
m = f.get_member('BC')
m.id, m.L, m.dcx, m.dcy
Out[13]:
In [14]:
%%Table node_loads
LOAD,NODEID,DIRN,F
Wind,B,FX,-200000.
In [15]:
@sl.extend(Frame2D)
class Frame2D:
COLUMNS_node_loads = ('LOAD','NODEID','DIRN','F')
def install_node_loads(self):
table = self.get_table('node_loads')
dirns = ['FX','FY','FZ']
for ix,row in table.data.iterrows():
n = self.get_node(row.NODEID)
if row.DIRN not in dirns:
raise ValueError("Invalid node load direction: {} for load {}, node {}; must be one of '{}'"
.format(row.DIRN, row.LOAD, row.NODEID, ', '.join(dirns)))
l = makeNodeLoad({row.DIRN:row.F})
self.nodeloads.append(row.LOAD,n,l)
self.rawdata.node_loads = table
In [16]:
##test:
f.install_node_loads()
In [17]:
##test:
for o,l,fact in f.nodeloads.iterloads('Wind'):
print(o,l,fact,l*fact)
In [18]:
%%Table member_loads
LOAD,MEMBERID,TYPE,W1,W2,A,B,C
Live,BC,UDL,-50,,,,
Live,BC,PL,-200000,,5000
In [19]:
@sl.extend(Frame2D)
class Frame2D:
COLUMNS_member_loads = ('LOAD','MEMBERID','TYPE','W1','W2','A','B','C')
def install_member_loads(self):
table = self.get_table('member_loads')
for ix,row in table.data.iterrows():
m = self.get_member(row.MEMBERID)
l = makeMemberLoad(m.L,row)
self.memberloads.append(row.LOAD,m,l)
self.rawdata.member_loads = table
In [20]:
##test:
f.install_member_loads()
In [21]:
##test:
for o,l,fact in f.memberloads.iterloads('Live'):
print(o.id,l,fact,l.fefs()*fact)
In [22]:
%%Table load_combinations
COMBO,LOAD,FACTOR
One,Live,1.5
One,Wind,1.75
In [23]:
@sl.extend(Frame2D)
class Frame2D:
COLUMNS_load_combinations = ('COMBO','LOAD','FACTOR')
def install_load_combinations(self):
table = self.get_table('load_combinations')
for ix,row in table.data.iterrows():
self.loadcombinations.append(row.COMBO,row.LOAD,row.FACTOR)
self.rawdata.load_combinations = table
In [24]:
##test:
f.install_load_combinations()
In [25]:
##test:
for o,l,fact in f.loadcombinations.iterloads('One',f.nodeloads):
print(o.id,l,fact)
for o,l,fact in f.loadcombinations.iterloads('One',f.memberloads):
print(o.id,l,fact,l.fefs()*fact)
In [26]:
@sl.extend(Frame2D)
class Frame2D:
def iter_nodeloads(self,comboname):
for o,l,f in self.loadcombinations.iterloads(comboname,self.nodeloads):
yield o,l,f
def iter_memberloads(self,comboname):
for o,l,f in self.loadcombinations.iterloads(comboname,self.memberloads):
yield o,l,f
In [27]:
##test:
for o,l,fact in f.iter_nodeloads('One'):
print(o.id,l,fact)
for o,l,fact in f.iter_memberloads('One'):
print(o.id,l,fact,l.fefs()*fact)
In [28]:
##test:
Table.CELLDATA
Out[28]: