Check Equilibrium

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]:
ID FXJ FYJ MZJ FXK FYK MZK
0 AB 994654.015809 -2177.821451 4.189959e+07 -994654.015809 2177.821451 -5.605543e+07
1 BC 452381.814808 -88371.309081 -2.410726e+08 -452381.814808 88371.309081 -2.449696e+08
2 DE 1055345.984190 63235.567017 1.843676e+08 -1055345.984190 -63235.567017 2.266636e+08
3 EF 470118.185192 115284.882504 2.959813e+08 -470118.185192 -115284.882504 3.380856e+08
4 IG 500000.000000 2308.981361 3.725290e-08 -500000.000000 -2308.981361 1.500838e+07
5 GH 225000.000000 -2728.796153 -1.500838e+07 -225000.000000 2728.796153 1.490116e-08
6 JK 500000.000000 1933.273074 0.000000e+00 -500000.000000 -1933.273074 1.256627e+07
7 KL 225000.000000 -2284.777269 -1.256627e+07 -225000.000000 2284.777269 0.000000e+00
8 CF 90656.086350 227381.814808 2.449696e+08 -90656.086350 245118.185192 -3.380856e+08
9 BE -90411.537973 267272.201001 2.971280e+08 90411.537973 310227.798999 -5.226449e+08
10 FH -24628.796153 225000.000000 0.000000e+00 24628.796153 225000.000000 0.000000e+00
11 EG -38362.222486 275000.000000 0.000000e+00 38362.222486 275000.000000 0.000000e+00
12 KB -4218.050343 275000.000000 0.000000e+00 4218.050343 275000.000000 0.000000e+00
13 LC 2284.777269 225000.000000 0.000000e+00 -2284.777269 225000.000000 0.000000e+00

14 rows × 7 columns


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]:
(1055345.98419, 522644884.38199997)

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]:
sumFX sumFY sumMZ
ID
H 0 0 0
D 0 0 0
G 0 0 0
K 0 0 0
C 0 0 0
I 0 0 0
E 0 0 0
L 0 0 0
J 0 0 0
F 0 0 0
B 0 0 0
A 0 0 0

12 rows × 3 columns


In [13]:
sums.abs().max()


Out[13]:
sumFX    0
sumFY    0
sumMZ    0
dtype: float64

In [ ]: