In [1]:
from sympy import *
init_printing(use_latex=True)
from IPython.display import display
from numpy import array
from scipy.linalg import eigh
from IPython.display import HTML
HTML(open("00_custom.css", "r").read())
Out[1]:
We are going to use a little symbolic algebra, hence we'll need the following base symbols:
In [2]:
x1, x2, x3, k, L, m = symbols('x1, x2, x3, k, L, m')
The single degrees of freedom have to be collected in a vector,
In [3]:
x = Matrix((x1,x2,x3))
x
Out[3]:
We want to compute the (double of the) strain energy, to do so we need the relative rotations, that we can compute if we know in advance the rotations of each individual bar...
In [9]:
phi1, phi2, phi3 = x1/L, (x2-x1)/L, (x3-x2)/L
phi21, phi32 = phi2-phi1, phi3-phi2
W2 = x2**2*k + phi21**2*k*L*L + phi32**2*k*L*L
print latex((W2/k).expand())
W2.expand()
Out[9]:
By comparison with the previuous expression, we have the stiffness matrix
In [6]:
K = k*Matrix(((5,-4,1),(-4,6,-2),(1,-2,1)))
K
Out[6]:
To compute the (double of the) kinetic energy, we have to compute the rotatory inertia and the displacements of the centers of the bars, as we have already computed the bars' rotations,
In [8]:
J = m*L*L/12
xg1, xg2, xg3 = x1/2, (x1+x2)/2, (x2+x3)/2
T2 = m*(xg1**2+xg2**2+xg3**2) + J*(phi1**2+phi2**2+phi3**2)
print latex((T2/m).expand())
T2.expand()
Out[8]:
Again, by comparison with the kinetic energy we can derive the mass matrix,
In [11]:
M = m*Matrix(((4,1,0),(1,4,1),(0,1,2)))/6
M
Out[11]:
Having computed, as requested, the structural matrices we are ready for the Rayleigh estimates, but first we define a trial vector and an auxiliary matrix, that we'll use in the following to simplify our lengthy expressions
In [12]:
x0 = Matrix((1,2,4))
D = K.inv()*M
Here are the expression for the energies, normalized with respect to $Z_0^2/2$
In [13]:
w2 = 1
V0 = (x0.T*K*x0)[0] * w2**0
T0 = (x0.T*M*x0)[0] * w2**1
V1 = (x0.T*M*D*x0)[0] * w2**2
T1 = (x0.T*M*D*D*x0)[0] * w2**3
V0, T0, V1, T1
Out[13]:
The Rayleigh estimates are as follows, fractions first and then floating point numbers
In [10]:
display(V0/T0, T0/V1, V1/T1)
map(N,(V0/T0, T0/V1, V1/T1))
Out[10]:
Just to be sure, a check with the results of a library function...
In [11]:
for x in eigh(
array(((5,-4,1),(-4,6,-2),(1,-2,1)))/1.,
array(((4,1,0),(1,4,1),(0,1,2)))/6., eigvals=(0,0)): print x