Some imports


In [1]:
from scipy import * ; from scipy.linalg import eigh

One utility function, to print a matrix in a format recognized by typesetting program


In [2]:
def lp(data,name,fmt="%+10.4f",title=""):
    delim={"mat":"b", "vet":"B", "det":"V", "norm":"v"}
    if title: print "% ----- "+title+" -----"
    print "\\begin{"+delim[name]+"matrix}"
    print "\\\\\n".join(["&".join(map(lambda x: fmt%(x,),line))
                         for line in asarray(data)])
    print "\\end{"+delim[name]+"matrix}"

Here a simple function to compute the DRV's as a function of the NDOFs "n" and of the load vector "r"


In [3]:
def derritz(n,r):
    #global T, phi

    phi = mat(zeros((n,n)))
    # y are the initial displacements
    y = F*r
    # normalization factor, note that M = I
    b = sqrt((y.T*y)[0,0])
    # normalize
    y = y/b
    # save the first DRV
    phi[:,0] = y[:,0]

    for i in range(1,n):
        # remember that M = I
        y = F*phi[:,i-1]
        alpha = y.T*phi
        for k in range(i):
            y=y-alpha[0,k]*phi[:,k]
        b=sqrt((y.T*y)[0,0])
        phi[:,i]=y[:,0]/b
    # remember that M = I    
    T=phi.T*F*phi
    # there are very small terms outside the tridiagonal part
    # this reduces T to a true tridiagonal matrix...
    T=(diagflat(diag(T))+
       diagflat(diag(T,1),1)+
       diagflat(diag(T,-1),-1))
    return phi, T

The problem data:


In [4]:
n=5

M=mat(eye(n))
K=mat(eye(n))*2
K[n-1,n-1]=1.
for i in range(n-1):
    K[i+1,i]=-1.
    K[i,i+1]=-1.
F=K.I

lp(M,'mat',title="Mass matrix   (=I) M")
lp(K,'mat',title="Stiffness matrix   K")
lp(F,'mat',title="Flexibility matrix F")

# evecs are normalized with respect to M
evals, evecs = eigh(K,M)
L=mat(diagflat(evals))
lp(L,'mat',title="Eigenvalues Matrix L")
lp(evecs,'mat',title="Eigenvectors matrix, \Psi")


% ----- Mass matrix   (=I) M -----
\begin{bmatrix}
   +1.0000&   +0.0000&   +0.0000&   +0.0000&   +0.0000\\
   +0.0000&   +1.0000&   +0.0000&   +0.0000&   +0.0000\\
   +0.0000&   +0.0000&   +1.0000&   +0.0000&   +0.0000\\
   +0.0000&   +0.0000&   +0.0000&   +1.0000&   +0.0000\\
   +0.0000&   +0.0000&   +0.0000&   +0.0000&   +1.0000
\end{bmatrix}
% ----- Stiffness matrix   K -----
\begin{bmatrix}
   +2.0000&   -1.0000&   +0.0000&   +0.0000&   +0.0000\\
   -1.0000&   +2.0000&   -1.0000&   +0.0000&   +0.0000\\
   +0.0000&   -1.0000&   +2.0000&   -1.0000&   +0.0000\\
   +0.0000&   +0.0000&   -1.0000&   +2.0000&   -1.0000\\
   +0.0000&   +0.0000&   +0.0000&   -1.0000&   +1.0000
\end{bmatrix}
% ----- Flexibility matrix F -----
\begin{bmatrix}
   +1.0000&   +1.0000&   +1.0000&   +1.0000&   +1.0000\\
   +1.0000&   +2.0000&   +2.0000&   +2.0000&   +2.0000\\
   +1.0000&   +2.0000&   +3.0000&   +3.0000&   +3.0000\\
   +1.0000&   +2.0000&   +3.0000&   +4.0000&   +4.0000\\
   +1.0000&   +2.0000&   +3.0000&   +4.0000&   +5.0000
\end{bmatrix}
% ----- Eigenvalues Matrix L -----
\begin{bmatrix}
   +0.0810&   +0.0000&   +0.0000&   +0.0000&   +0.0000\\
   +0.0000&   +0.6903&   +0.0000&   +0.0000&   +0.0000\\
   +0.0000&   +0.0000&   +1.7154&   +0.0000&   +0.0000\\
   +0.0000&   +0.0000&   +0.0000&   +2.8308&   +0.0000\\
   +0.0000&   +0.0000&   +0.0000&   +0.0000&   +3.6825
\end{bmatrix}
% ----- Eigenvectors matrix, \Psi -----
\begin{bmatrix}
   +0.1699&   -0.4557&   +0.5969&   +0.5485&   -0.3260\\
   +0.3260&   -0.5969&   +0.1699&   -0.4557&   +0.5485\\
   +0.4557&   -0.3260&   -0.5485&   -0.1699&   -0.5969\\
   +0.5485&   +0.1699&   -0.3260&   +0.5969&   +0.4557\\
   +0.5969&   +0.5485&   +0.4557&   -0.3260&   -0.1699
\end{bmatrix}

Let's set a particular load vector, compute the DRVs and show the results


In [5]:
r = mat((0,0,0,-2.,1.)).T
lp(r.T,'vet',title="Load vector transposed r^T")
phi, T = derritz(n,r)
lp(phi,'mat',title="Derived Ritz Vectors matrix \Phi")
lp(T,'mat',title="Tridiagonal DRV matrix, T")


% ----- Load vector transposed r^T -----
\begin{Bmatrix}
   +0.0000&   +0.0000&   +0.0000&   -2.0000&   +1.0000
\end{Bmatrix}
% ----- Derived Ritz Vectors matrix \Phi -----
\begin{bmatrix}
   -0.1601&   -0.0843&   +0.2442&   +0.6442&   +0.7019\\
   -0.3203&   -0.0773&   +0.5199&   +0.4317&   -0.6594\\
   -0.4804&   +0.1125&   +0.5627&   -0.6077&   +0.2659\\
   -0.6405&   +0.5764&   -0.4841&   +0.1461&   -0.0425\\
   -0.4804&   -0.8013&   -0.3451&   -0.0897&   -0.0035
\end{bmatrix}
% ----- Tridiagonal DRV matrix, T -----
\begin{bmatrix}
  +12.0769&   +1.7524&   +0.0000&   +0.0000&   +0.0000\\
   +1.7524&   +0.8165&   +0.3086&   +0.0000&   +0.0000\\
   +0.0000&   +0.3086&   +1.1895&   +0.3618&   +0.0000\\
   +0.0000&   +0.0000&   +0.3618&   +0.6046&   +0.0667\\
   +0.0000&   +0.0000&   +0.0000&   +0.0667&   +0.3125
\end{bmatrix}

Compute the modal partecipation factors, for the eigenvectors and for the DRVs, and the decomposition in modal forces and DRV forces


In [6]:
Gamma=evecs.T*r ; Gammh=phi.T*r
f_m=M*evecs*diagflat(Gamma)
f_r=M*phi*diagflat(Gammh)

lp(Gamma.T,'vet',title="Modal partecipation factors")
lp(Gammh.T,'vet',title="DRV's partecipation factors")
lp(f_m,'mat',title="Modal forces matrix")
lp(f_r,'mat',title="DRV's forces matrix")


% ----- Modal partecipation factors -----
\begin{Bmatrix}
   -0.5002&   +0.2087&   +1.1078&   -1.5198&   -1.0814
\end{Bmatrix}
% ----- DRV's partecipation factors -----
\begin{Bmatrix}
   +0.8006&   -1.9540&   +0.6231&   -0.3819&   +0.0815
\end{Bmatrix}
% ----- Modal forces matrix -----
\begin{bmatrix}
   -0.0850&   -0.0951&   +0.6612&   -0.8336&   +0.3525\\
   -0.1631&   -0.1246&   +0.1882&   +0.6926&   -0.5932\\
   -0.2279&   -0.0681&   -0.6076&   +0.2582&   +0.6454\\
   -0.2744&   +0.0355&   -0.3612&   -0.9071&   -0.4928\\
   -0.2985&   +0.1145&   +0.5048&   +0.4955&   +0.1837
\end{bmatrix}
% ----- DRV's forces matrix -----
\begin{bmatrix}
   -0.1282&   +0.1648&   +0.1521&   -0.2460&   +0.0572\\
   -0.2564&   +0.1511&   +0.3240&   -0.1649&   -0.0538\\
   -0.3846&   -0.2198&   +0.3506&   +0.2321&   +0.0217\\
   -0.5128&   -1.1262&   -0.3017&   -0.0558&   -0.0035\\
   -0.3846&   +1.5657&   -0.2151&   +0.0342&   -0.0003
\end{bmatrix}

In [7]:
den=dot(r.T,r)[0,0] ; e_m = r ; e_r = r
for i in range(n):
    e_m = e_m-f_m[:,i]
    e_r = e_r-f_r[:,i]
    print "%3d   %10.7f   %10.7f" % (
              i+1, 
              dot(r.T,e_m)[0,0]/den,
              dot(r.T,e_r)[0,0]/den )


  1    0.9499655    0.8717949
  2    0.9412504    0.1081567
  3    0.6958189    0.0304958
  4    0.2338676    0.0013296
  5   -0.0000000    0.0000000

In [7]: