a mechanical engineering toolbox
source code - https://github.com/nagordon/mechpy
documentation - https://nagordon.github.io/mechpy/web/
Neal Gordon
2017-02-20
# setup
import numpy as np
import sympy as sp
import scipy
from pprint import pprint
sp.init_printing(use_latex='mathjax')
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (12, 8) # (width, height)
plt.rcParams['font.size'] = 14
plt.rcParams['legend.fontsize'] = 16
from matplotlib import patches
get_ipython().magic('matplotlib') # seperate window
get_ipython().magic('matplotlib inline') # inline plotting
def T1(th):
'''Stress Transform for Plane Stress
th=ply angle in degrees
voight notation for stress tranform. sigma1 = T1 @ sigmax
recall T1(th)**-1 == T1(-th)'''
n = np.sin(th*np.pi/180)
m = np.cos(th*np.pi/180)
T1 = np.array( [[m**2, n**2, 2*m*n],
[n**2, m**2,-2*m*n],
[-m*n, m*n,(m**2-n**2)]])
return T1
def T2(th):
'''Strain Transform for Plane Stress
th=ply angle in degrees
voight notation for strain transform. epsilon1 = T2 @ epsilonx'''
n = np.sin(th*np.pi/180)
m = np.cos(th*np.pi/180)
T2 = np.array( [[m**2, n**2, m*n],
[n**2, m**2,-m*n],
[-2*m*n, 2*m*n, (m**2-n**2)]])
return T2
reduce to plane stress
$$ \overline{\sigma}=\begin{bmatrix} \sigma_{xx} & \sigma_{xy} & 0 \\ \sigma_{yx} & \sigma_{yy} & 0\\ 0 & 0 & \sigma_{zz} \end{bmatrix} $$or
$$ \overline{\sigma}=\begin{bmatrix} \sigma_{xx} & \tau_{xy} & 0 \\ \tau_{yx} & \sigma_{yy} & 0\\ 0 & 0 & \sigma_{zz} \end{bmatrix} $$$$ \overline{\sigma}=\begin{bmatrix} \sigma_{x} & \sigma_{xy} \\ \sigma_{yx} & \sigma_{y} \\ \end{bmatrix} $$Transformation
$$ A=\begin{bmatrix} cos(\theta) & sin(\theta) \\ -sin(\theta) & cos(\theta) \\ \end{bmatrix} $$$$ \sigma'=A \sigma A^T $$$$ \sigma_1 , \sigma_2 = \frac{\sigma_{x}}{2} + \frac{\sigma_{y}}{2} + \sqrt{\tau_{xy}^{2} + \left(\frac{\sigma_{x}}{2} - \frac{\sigma_{y}}{2}\right)^{2}} $$$$ T=\left[\begin{matrix}\sin^{2}{\left (\theta \right )} & \cos^{2}{\left (\theta \right )} & 2 \sin{\left (\theta \right )} \cos{\left (\theta \right )}\cos^{2}{\left (\theta \right )} & \\ \sin^{2}{\left (\theta \right )} & - 2 \sin{\left (\theta \right )} \cos{\left (\theta \right )}\- \sin{\left (\theta \right )} \cos{\left (\theta \right )} & \\ \sin{\left (\theta \right )} \cos{\left (\theta \right )} & \sin^{2}{\left (\theta \right )} - \cos^{2}{\left (\theta \right )}\end{matrix}\right] $$import sympy as sp
from sympy.abc import tau, sigma
import numpy as np
sp.init_printing()
sx,sy,txy,tp = sp.symbols('sigma_x,sigma_y,tau_xy,theta_p')
sp1 = (sx+sy)/2 + sp.sqrt( ((sx-sy)/2)**2 + txy**2 )
sp2 = (sx+sy)/2 - sp.sqrt( ((sx-sy)/2)**2 + txy**2 )
print(sp.latex(sp1))
sp1
tp = sp.atan(2*txy/(sx-sy) )/2
tp
tpp = tp.evalf(subs={sx:10,sy:15,txy:10})
tpp
#s,s11,s22,s33,s12 = sp.var('s,s11,s22,s33,s12')
s,s11,s22,s33,s12,s13,t,t12 = sp.symbols('sigma, sigma11,sigma22,sigma33,sigma12,sigma13,tau,tau12')
s = sp.Matrix([[s11,t12,0],[t12,s22,0],[0,0,s33]])
s
t = sp.symbols('theta')
m = sp.sin(t)
n = sp.cos(t)
T = sp.Matrix([[m**2,n**2, 2*m*n],[n**2,m**2,-2*m*n],[-m*n,m*n,m**2-n**2]])
T
T1 = T.subs(t, sp.pi/4)
T1
sprime = T1 * s * T1.inv()
sprime
sprime.evalf(subs={s11:10, s22:00, s33:0, t12:0})
s.eigenvals()
s2 = s.evalf(subs={s11:2.2, s22:3, s33:sp.pi, s12:7.3})
s2
%matplotlib inline
cd ..
from mechpy.math import T2rot
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
mpl.rcParams['figure.figsize'] = (10,8)
from IPython.html.widgets import *
from mechpy.math import T2rot
#x = [-1,1, 0,-1,]
#y = [-1,-1,1,-1]
#xy = np.array([x,y])
#plt.xlim([-11.1,11.1])
#plt.ylim([-11.1,11.1])
#xyR = np.dot(T2rot(30),xy)
#plt.plot(xyR[0,:],xyR[1,:])
fig1 = plt.figure(figsize=(10,8))
def rot2(th, xt,yt,zt):
xyR = np.dot(T2rot(th),xy*zt)
xyR[0,:]+=xt
xyR[1,:]+=yt
plt.plot(xyR[0,:],xyR[1,:])
plt.axis('square')
plt.xlim([-11.1,11.1])
plt.ylim([-11.1,11.1])
plt.show()
interact(rot2, th=(0,np.pi,np.pi/90), yt=(1,10,1), xt=(1,10,1), zt=(1,10,1));
# stress angle transformation
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['figure.figsize'] = (10,8)
mpl.rcParams['font.size'] = 16
mpl.rcParams['legend.fontsize'] = 14
plt.figure(figsize=(10,8))
def mohr(sigmax, sigmay, tauxy, angle):
plt.figure(figsize=(10,8))
# angle rotates clockwise
theta = (angle-90) * np.pi/180
# stress transformed to any angle
sigmaxt = (sigmax + sigmay)/2 + (sigmax-sigmay)/2 * np.cos(2*theta) + tauxy*np.sin(2*theta)
sigmayt = (sigmax + sigmay)/2 + (sigmax-sigmay)/2 * np.cos(2*(theta + np.pi/2)) + tauxy*np.sin(2*(theta+ np.pi/2))
tauxyt = -(sigmax-sigmay)/2*np.sin(2*theta) + tauxy*np.cos(2*theta)
print('transformed stress')
print([sigmaxt, sigmayt, tauxyt])
# principal stresses
sigma1p = (sigmaxt + sigmayt)/2 + np.sqrt( ((sigmaxt-sigmayt)/2)**2 + tauxyt**2)
sigma2p = (sigmaxt + sigmayt)/2 - np.sqrt( ((sigmaxt-sigmayt)/2)**2 + tauxyt**2)
tauxyp = np.sqrt( ( (sigmaxt-sigmayt)/2 )**2 + tauxyt**2 )
sigmap = [sigma1p, sigma2p]
thetap = -np.arctan(tauxyt/ ((sigmaxt-sigmayt)/2)) / 2 * 180 / np.pi
sigmaavg = (sigma1p+sigma2p)/2
R = np.sqrt(((sigmaxt-sigmayt)/2)**2 + tauxyt**2)
print('---principal stresses---')
print('sigma1p = {:.2f}'.format(sigma1p) )
print('sigma2p = {:.2f}'.format(sigma2p) )
print('principal plane angle = {:.2f}'.format(thetap) )
print('---principal shear---')
print('tauxyp = {:.2f} with avg normal stress = {:.2f}'.format(tauxyp,sigmaavg))
r = np.linspace(-2*np.pi,2*np.pi,100)
## keep this for sigma3
# x = np.cos(r) * (sigma1p/2) + sigma1p/2
# y = np.sin(r) * (sigma1p/2)
# plt.plot(x,y,'bo', sigmaavg,0,'bo')
# x = np.cos(r) * (sigma2p/2) + sigma2p/2
# y = np.sin(r) * (sigma2p/2)
# plt.plot(x,y,'bo', sigmaavg,0,'bo')
x = np.cos(r) * R + sigmaavg
y = np.sin(r) * R
plt.plot(x,y,'b', sigmaavg,0,'bo')
plt.plot([sigmaxt,sigmayt],[tauxyt, -tauxyt], 'g-o', label='applied stress');
plt.plot([sigma1p,sigma2p],[0,0],'ro');
plt.plot([sigmaavg,sigmaavg],[tauxyp,-tauxyp], 'ro', label='principal stress');
plt.plot([sigmaxt,sigmaxt],[tauxyt, 0], '--g'); plt.plot([sigmaxt,sigmaxt],[tauxyt, 0], 'og');
plt.plot([sigmayt,sigmayt],[-tauxyt, 0], '--g'); plt.plot([sigmayt,sigmayt],[-tauxyt, 0], 'og');
plt.plot([sigmaavg, sigmaxt],[tauxyt, tauxyt], '--g'); plt.plot([sigmaavg, sigmaxt],[tauxyt, tauxyt], 'og');
plt.plot([sigmaavg, sigmayt],[-tauxyt, -tauxyt], '--g'); plt.plot([sigmaavg, sigmayt],[-tauxyt, -tauxyt], 'og');
plt.axis('equal') ; plt.grid();
plt.xlabel('$\sigma_x,\sigma_y$');
plt.ylabel('$\\tau_{xy}$');
plt.title('Mohrs Circle 2D Plane Stress ');
plt.legend();
interact(mohr, sigmax=(0,500,10),sigmay=(0,500,10),tauxy=(0,500,10),angle=(0,90,5));
# stress angle transformation
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['figure.figsize'] = (10,8)
mpl.rcParams['font.size'] = 16
mpl.rcParams['legend.fontsize'] = 14
sigmax = -20
sigmay = 0
tauxy = 40
angle = 0
# angle rotates clockwise
theta = (angle-90) * np.pi/180
# stress transformed to any angle
sigmaxt = (sigmax + sigmay)/2 + (sigmax-sigmay)/2 * np.cos(2*theta) + tauxy*np.sin(2*theta)
sigmayt = (sigmax + sigmay)/2 + (sigmax-sigmay)/2 * np.cos(2*(theta + np.pi/2)) + tauxy*np.sin(2*(theta+ np.pi/2))
tauxyt = -(sigmax-sigmay)/2*np.sin(2*theta) + tauxy*np.cos(2*theta)
print('transformed stress')
print([sigmaxt, sigmayt, tauxyt])
# principal stresses
sigma1p = (sigmaxt + sigmayt)/2 + np.sqrt( ((sigmaxt-sigmayt)/2)**2 + tauxyt**2)
sigma2p = (sigmaxt + sigmayt)/2 - np.sqrt( ((sigmaxt-sigmayt)/2)**2 + tauxyt**2)
tauxyp = np.sqrt( ( (sigmaxt-sigmayt)/2 )**2 + tauxyt**2 )
sigmap = [sigma1p, sigma2p]
thetap = -np.arctan(tauxyt/ ((sigmaxt-sigmayt)/2)) / 2 * 180 / np.pi
sigmaavg = (sigma1p+sigma2p)/2
R = np.sqrt(((sigmaxt-sigmayt)/2)**2 + tauxyt**2)
print('---principal stresses---')
print('sigma1p = {:.2f}'.format(sigma1p) )
print('sigma2p = {:.2f}'.format(sigma2p) )
print('principal plane angle = {:.2f}'.format(thetap) )
print('---principal shear---')
print('tauxyp = {:.2f} with avg normal stress = {:.2f}'.format(tauxyp,sigmaavg))
r = np.linspace(-2*np.pi,2*np.pi,100)
## keep this for sigma3
# x = np.cos(r) * (sigma1p/2) + sigma1p/2
# y = np.sin(r) * (sigma1p/2)
# plt.plot(x,y,'bo', sigmaavg,0,'bo')
# x = np.cos(r) * (sigma2p/2) + sigma2p/2
# y = np.sin(r) * (sigma2p/2)
# plt.plot(x,y,'bo', sigmaavg,0,'bo')
x = np.cos(r) * R + sigmaavg
y = np.sin(r) * R
plt.plot(x,y,'b', sigmaavg,0,'bo')
plt.plot([sigmaxt,sigmayt],[tauxyt, -tauxyt], 'g-o', label='applied stress');
plt.plot([sigma1p,sigma2p],[0,0],'ro');
plt.plot([sigmaavg,sigmaavg],[tauxyp,-tauxyp], 'ro', label='principal stress');
plt.plot([sigmaxt,sigmaxt],[tauxyt, 0], '--g'); plt.plot([sigmaxt,sigmaxt],[tauxyt, 0], 'og');
plt.plot([sigmayt,sigmayt],[-tauxyt, 0], '--g'); plt.plot([sigmayt,sigmayt],[-tauxyt, 0], 'og');
plt.plot([sigmaavg, sigmaxt],[tauxyt, tauxyt], '--g'); plt.plot([sigmaavg, sigmaxt],[tauxyt, tauxyt], 'og');
plt.plot([sigmaavg, sigmayt],[-tauxyt, -tauxyt], '--g'); plt.plot([sigmaavg, sigmayt],[-tauxyt, -tauxyt], 'og');
plt.axis('equal') ; plt.grid();
plt.xlabel('$\sigma_x,\sigma_y$');
plt.ylabel('$\\tau_{xy}$');
plt.title('Mohrs Circle 2D Plane Stress ');
plt.legend();
# Principal PLane Stress
sigmax = -20
sigmay = 90
tauxy = 60
sigma = np.array([[sigmax, tauxy, 0],
[tauxy, sigmay,0],
[0, 0, 0]])
sigmap = np.linalg.eig(sigma)[0]
print('\n principal stresses')
print(sigmap)
thetap = np.linalg.eig(sigma)[1] # principal cosine angle
print('\n principal plane angle')
print(np.arccos(thetap)*180/np.pi-90)
# specified angle stress transformation
sigmax = -20
sigmay = 90
tauxy = 60
sigma = np.array([[sigmax, tauxy, 0],
[tauxy, sigmay,0],
[0, 0, 0]])
ang = 23
sigmat = T1(ang) @ sigma @ np.transpose(T1(ang))
print('\n transformed stresses')
print(sigmat)
# maximum in-plane shear stress
eps = 1e-16 # machine epsilon to avoid divide-by-zero error
rad_to_deg = 180/np.pi
theta1 = 0.5 * np.arctan( 2*tauxy / ((sigmax-sigmay+eps))) * rad_to_deg
print(theta1)
tauxy = 0 # lbs/in
sigmax = 100 # lbs/in
sigmay = np.linspace(0,1.100) # lbs/in
eps = 1e-16 # machine epsilon to avoid divide-by-zero error
rad_to_deg = 180/np.pi
theta1 = 0.5 * np.arctan( 2*tauxy / ((sigmax-sigmay+eps))) * rad_to_deg
print(theta1)
# sigmax = 100
# sigmay = np.linspace(0,1.100)
# tauxy = 0
# tparray = sp.atan(2*tauxy/(sigmax-sigmay) )/2
# tparray
sigma
th = np.pi/4 # 45 deg
m = np.cos(th)
n = np.sin(th)
A = np.array([ [m,n],[-n,m]])
tauxy = 1 # lbs/in
sigmax = 0 # lbs/in
sigmay = 0 # lbs/in
sigma = np.array([[sigmax, tauxy],
[tauxy, sigmay]])
sigmat = A @ sigma @ A.T # transformed stress
sigmat
sigmap = np.linalg.eig(sigmat)[0] # principal stresses
print(sigmap)
thetap = np.linalg.eig(sigmat)[1] # principal planes
print(thetap* 180/np.pi)
# Principal Stresses
sx = 63.66
sy = 0
sz = 0
txy = 63.66
txz = 0
tyz = 0
S = np.matrix([[sx, txy, txz],
[txy, sy, tyz],
[txy, txz, sz]])
print(S)
principal_stresses = np.linalg.eigvals(S)
print(principal_stresses)
import sympy as sp
from sympy.abc import tau, sigma
#s,s11,s22,s33,s12 = sp.var('s,s11,s22,s33,s12')
s,s11,s22,s33,s12,s13 = sp.symbols('sigma, sigma11,sigma22,sigma33,sigma12,sigma13')
s = sp.Matrix([[s11,s12,0],[s12,s22,0],[0,0,s33]])
s
s**2
s.eigenvals() # hmm looks familiar
s1 = s.subs(s11,2.2).subs(s22,3).subs(s33,sp.pi).subs(s12,7.3)
s1
# or
s2 = s.evalf(subs={s11:2.2, s22:3, s33:sp.pi, s12:7.3})
s2
s1.eigenvals()
s2.eigenvals()
s2.inv()
C = sp.symbols('C1:100')
C