This notebook reads files describing a structure, and the files output by Frame2D after an analysis, and checks that the forces and moments on every node are in equilibrium.
It does this in the simplest way possible, using quite different logic than Frame2D, resulting in a higher degree of confidence in the results. It would have been better had someone else programmed it, but oh well ...
In [1]:
dir = 'KG82.d'
#dir = 'l22x6.d'
#dir = 'l22x6pd.d'
def filename(basename):
return dir + '/' + basename + '.csv'
def Warn(msg):
print('!!!!! Warning: {}'.format(msg))
In [2]:
import pandas as pd
import math
In [3]:
class Node(object):
def __init__(self,id,x,y):
self.id = id
self.x = x
self.y = y
self.sumFX = 0.
self.sumFY = 0.
self.sumMZ = 0.
In [4]:
table = pd.read_csv(filename('nodes'))
NODES = {}
for i,n in table.iterrows():
if n.ID in NODES:
Warn("Node '{}' is multiply defined.".format(n.ID))
NODES[n.ID] = Node(n.ID,float(n.X),float(n.Y))
In [5]:
class Member(object):
def __init__(self,id,nodej,nodek):
self.id = id
self.nodej = nodej
self.nodek = nodek
dx = nodek.x - nodej.x
dy = nodek.y - nodej.y
self.L = L = math.sqrt(dx*dx + dy*dy)
self.cosx = dx/L
self.cosy = dy/L
In [6]:
table = pd.read_csv(filename('members'))
MEMBERS = {}
for i,m in table.iterrows():
if m.ID in MEMBERS:
Warn("Member '{}' is multiply defined.".format(m.ID))
MEMBERS[m.ID] = Member(m.ID,NODES[m.NODEJ],NODES[m.NODEK])
In [7]:
table = pd.read_csv(filename('node_loads'))
for i,p in table.iterrows():
dirn = p.DIRN.upper()
if dirn in ['FX','FY','MZ']:
n = NODES[p.ID]
a = 'sum'+dirn
setattr(n,a,getattr(n,a,0.)+float(p.F))
else:
Warn("Direction '{}' invalid for node '{}'.".format(dirn,p.ID))
In [8]:
try:
table = pd.read_csv(filename('pdelta_forces'))
for i,p in table.iterrows():
dirn = p.DIRN.upper()
if dirn in ['FX','FY','MZ']:
n = NODES[p.ID]
a = 'sum'+dirn
setattr(n,a,getattr(n,a,0.)+float(p.F))
else:
Warn("Direction '{}' invalid for node '{}'.".format(dirn,p.ID))
except OSError:
pass
In [9]:
table = pd.read_csv(filename('reactions'))
for i,r in table.iterrows():
n = NODES[r.ID]
n.sumFX += 0. if pd.isnull(r.FX) else float(r.FX)
n.sumFY += 0. if pd.isnull(r.FY) else float(r.FY)
n.sumMZ += 0. if pd.isnull(r.MZ) else float(r.MZ)
In [10]:
mtable = pd.read_csv(filename('mefs'))
for i,row in mtable.iterrows():
m = MEMBERS[row.ID]
n = m.nodej
n.sumFX -= row.FXJ*m.cosx - row.FYJ*m.cosy
n.sumFY -= row.FXJ*m.cosy + row.FYJ*m.cosx
n.sumMZ -= row.MZJ
n = m.nodek
n.sumFX -= row.FXK*m.cosx - row.FYK*m.cosy
n.sumFY -= row.FXK*m.cosy + row.FYK*m.cosx
n.sumMZ -= row.MZK
mtable
Out[10]:
In [11]:
maxF = max([mtable[c].abs().max() for c in 'FXJ FXK FYJ FYK'.split()])
maxM = max([mtable[c].abs().max() for c in 'MZJ MZK'.split()])
maxF,maxM
Out[11]:
In [12]:
sums = pd.DataFrame([(n.id,n.sumFX,n.sumFY,n.sumMZ) for n in NODES.values()],
columns=['ID','sumFX','sumFY','sumMZ']).set_index(['ID'])
sums
lm = 1E-11
sums['sumFX'][sums['sumFX'].abs() <= maxF*lm] = 0
sums['sumFY'][sums['sumFY'].abs() <= maxF*lm] = 0
sums['sumMZ'][sums['sumMZ'].abs() <= maxM*lm] = 0
sums
Out[12]:
In [13]:
sums.abs().max()
Out[13]:
In [ ]: