# Semi-Monocoque Theory: corrective solutions



In [1]:

from pint import UnitRegistry
import sympy
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import sys
%matplotlib inline
from IPython.display import display



Import Section class, which contains all calculations



In [2]:

from Section import Section



Initialization of sympy symbolic tool and pint for dimension analysis (not really implemented rn as not directly compatible with sympy)



In [3]:

ureg = UnitRegistry()
sympy.init_printing()



Define sympy parameters used for geometric description of sections



In [4]:

A, A0, t, t0, a, b, h, L, E, G = sympy.symbols('A A_0 t t_0 a b h L E G', positive=True)



We also define numerical values for each symbol in order to plot scaled section and perform calculations



In [5]:

values = [(A, 150 * ureg.millimeter**2),(A0, 250  * ureg.millimeter**2),(a, 400 * ureg.millimeter), \
(b, 20 * ureg.millimeter),(h, 150 * ureg.millimeter),(L, 2000 * ureg.millimeter), \
(t, 0.8 *ureg.millimeter),(E, 72e3 * ureg.MPa), (G, 28e3 * ureg.MPa)]
datav = [(v[0],v[1].magnitude) for v in values]



# First example: Simple rectangular symmetric section

Define graph describing the section:

1) stringers are nodes with parameters:

• x coordinate
• y coordinate
• Area

2) panels are oriented edges with parameters:

• thickness
• lenght which is automatically calculated


In [6]:

stringers = {1:[(a,h),A],
2:[(sympy.Rational(1,2)*a,h),A],
3:[(sympy.Integer(0),h),A],
4:[(sympy.Integer(0),sympy.Integer(0)),A],
5:[(sympy.Rational(1,2)*a,sympy.Integer(0)),A],
6:[(a,sympy.Integer(0)),A]}

panels = {(1,2):t,
(3,4):t,
(4,5):t,
(5,6):t,
(6,1):t,
(5,2):t}



Define section and perform first calculations



In [7]:

S1 = Section(stringers, panels)




In [8]:

S1.cycles




Out[8]:

$$\left [ \left [ 2, \quad 5, \quad 6, \quad 1, \quad 2\right ]\right ]$$



## Plot of S1 section in original reference frame

Define a dictionary of coordinates used by Networkx to plot section as a Directed graph. Note that arrows are actually just thicker stubs



In [9]:

start_pos={ii: [float(S1.g.node[ii]['ip'][i].subs(datav)) for i in range(2)] for ii in S1.g.nodes() }




In [10]:

plt.figure(figsize=(12,8),dpi=300)
nx.draw(S1.g,with_labels=True, arrows= True, pos=start_pos)
plt.arrow(0,0,20,0)
plt.arrow(0,0,0,20)
#plt.text(0,0, 'CG', fontsize=24)
plt.axis('equal')
plt.title("Section in starting reference Frame",fontsize=16);






## Plot of S1 section in inertial reference Frame

Section is plotted wrt center of gravity and rotated (if necessary) so that x and y are principal axes. Center of Gravity and Shear Center are drawn



In [11]:

positions={ii: [float(S1.g.node[ii]['pos'][i].subs(datav)) for i in range(2)] for ii in S1.g.nodes() }




In [12]:

x_ct, y_ct = S1.ct.subs(datav)

plt.figure(figsize=(12,8),dpi=300)
nx.draw(S1.g,with_labels=True, pos=positions)
plt.plot([0],[0],'o',ms=12,label='CG')
plt.plot([x_ct],[y_ct],'^',ms=12, label='SC')
#plt.text(0,0, 'CG', fontsize=24)
#plt.text(x_ct,y_ct, 'SC', fontsize=24)
plt.axis('equal')
plt.title("Section in pricipal reference Frame",fontsize=16);






## Standard Solution



In [13]:

Tx, Ty, Nz, Mx, My, Mz, F, ry, ry, mz = sympy.symbols('T_x T_y N_z M_x M_y M_z F r_y r_x m_z')




In [14]:

S1.set_loads(_Tx=0, _Ty=0, _Nz=0, _Mx=0, _My=0, _Mz=Mz)





In [15]:

S1.compute_stringer_actions()
S1.compute_panel_fluxes();




In [16]:

S1.N




Out[16]:

$$\left \{ 1 : 0, \quad 2 : 0, \quad 3 : 0, \quad 4 : 0, \quad 5 : 0, \quad 6 : 0\right \}$$




In [17]:

S1.q




Out[17]:

$$\left \{ \left ( 1, \quad 2\right ) : \frac{M_{z}}{a h}, \quad \left ( 3, \quad 4\right ) : 0, \quad \left ( 4, \quad 5\right ) : 0, \quad \left ( 5, \quad 2\right ) : - \frac{M_{z}}{a h}, \quad \left ( 5, \quad 6\right ) : \frac{M_{z}}{a h}, \quad \left ( 6, \quad 1\right ) : \frac{M_{z}}{a h}\right \}$$




In [31]:

S1.set_loads(_Tx=0, _Ty=Ty, _Nz=0, _Mx=Mx, _My=0, _Mz=0)




In [32]:

S1.compute_stringer_actions()
S1.compute_panel_fluxes();




In [33]:

S1.N




Out[33]:

$$\left \{ 1 : \frac{M_{x}}{3 h}, \quad 2 : \frac{M_{x}}{3 h}, \quad 3 : \frac{M_{x}}{3 h}, \quad 4 : - \frac{M_{x}}{3 h}, \quad 5 : - \frac{M_{x}}{3 h}, \quad 6 : - \frac{M_{x}}{3 h}\right \}$$




In [34]:

S1.q




Out[34]:

$$\left \{ \left ( 1, \quad 2\right ) : 0, \quad \left ( 3, \quad 4\right ) : - \frac{T_{y}}{3 h}, \quad \left ( 4, \quad 5\right ) : 0, \quad \left ( 5, \quad 2\right ) : \frac{T_{y}}{3 h}, \quad \left ( 5, \quad 6\right ) : 0, \quad \left ( 6, \quad 1\right ) : \frac{T_{y}}{3 h}\right \}$$



# Autosolutions

Compute L matrix: with 6 nodes we expect 3 dofs, one with symmetric load and one with antisymmetric load



In [18]:

S1.compute_L()




In [19]:

S1.L




Out[19]:

$$\left[\begin{matrix}- \frac{1}{2} & - \frac{1}{2} & -1\\1 & 0 & 0\\- \frac{1}{2} & \frac{1}{2} & 1\\0 & -1 & -1\\0 & 1 & 0\\0 & 0 & 1\end{matrix}\right]$$



Compute H matrix



In [20]:

S1.compute_H()




In [21]:

S1.H




Out[21]:

$$\left[\begin{matrix}0 & \frac{1}{2} & 1\\\frac{1}{2} & - \frac{1}{2} & -1\\\frac{1}{2} & \frac{1}{2} & 0\\1 & - \frac{1}{2} & -1\\- \frac{1}{2} & 0 & 1\\- \frac{1}{2} & 0 & 0\end{matrix}\right]$$



Compute $\tilde{K}$ and $\tilde{M}$ as:

$$\tilde{K} = L^T \cdot \left[ \frac{A}{A_0} \right] \cdot L$$$$\tilde{M} = H^T \cdot \left[ \frac{l}{l_0}\frac{t_0}{t} \right] \cdot L$$


In [22]:

S1.compute_KM(A,a/2,t,datav)




In [29]:

S1.Ktilde




Out[29]:

$$\left[\begin{matrix}\frac{3}{2} & 0 & 0\\0 & \frac{5}{2} & 2\\0 & 2 & 4\end{matrix}\right]$$




In [30]:

S1.Mtilde




Out[30]:

$$\left[\begin{matrix}\frac{13}{8} & - \frac{5}{16} & - \frac{13}{8}\\- \frac{5}{16} & \frac{7}{8} & \frac{5}{4}\\- \frac{13}{8} & \frac{5}{4} & \frac{7}{2}\end{matrix}\right]$$



Compute eigenvalues and eigenvectors as:

$$\left| \mathbf{I} \cdot \beta^2 - \mathbf{\tilde{K}}^{-1} \cdot \mathbf{\tilde{M}} \right| = 0$$

We substitute some numerical values to simplify the expressions



In [25]:

sol_data = (sympy.N(S1.Ktilde.subs(datav).inv())*(sympy.N(S1.Mtilde.subs(datav)))).eigenvects()



Eigenvalues correspond to $\beta^2$



In [26]:

β2 = [sol[0] for sol in sol_data]
β2




Out[26]:

$$\left [ 0.339290414631418 - 3.0 \cdot 10^{-23} i, \quad 0.196731067901288 + 1.0 \cdot 10^{-23} i, \quad 1.75564518413396 - 2.0 \cdot 10^{-22} i\right ]$$



Eigenvectors are orthogonal as expected



In [27]:

X = [sol[2][0] for sol in sol_data]
X




Out[27]:

$$\left [ \left[\begin{matrix}1.99278837919186 - 1.2229017886908 \cdot 10^{-23} i\\1.91705639364402 - 1.26385682555636 \cdot 10^{-25} i\\1.0\end{matrix}\right], \quad \left[\begin{matrix}0.861773743111062 - 8.0 \cdot 10^{-25} i\\-1.53255734592582 + 2.62670292138894 \cdot 10^{-23} i\\1.0\end{matrix}\right], \quad \left[\begin{matrix}-1.45196471970552 - 1.93261773279565 \cdot 10^{-30} i\\-0.514369177588328 + 2.45344342718328 \cdot 10^{-28} i\\1.0\end{matrix}\right]\right ]$$



From $\beta_i^2$ we compute: $$\lambda_i = \sqrt{\frac{E A_0 l_0}{G t_0} \beta_i^2}$$

substuting numerical values



In [28]:

λ = [sympy.N(sympy.sqrt(E*A*b/(G*t)*βi).subs(datav)) for βi in β2]
λ




Out[28]:

$$\left [ 57.1990296965913 - 2.23119434591815 \cdot 10^{-21} i, \quad 43.5551326864452 + 1.46506443419418 \cdot 10^{-21} i, \quad 130.113164991668 - 7.84684019694465 \cdot 10^{-21} i\right ]$$




In [ ]: