-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPolyMAX.py
More file actions
83 lines (78 loc) · 3.19 KB
/
Copy pathPolyMAX.py
File metadata and controls
83 lines (78 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
def PolyMAX(FRF, Freq, Coh, min_freq, max_freq, Nmin, Nmax):
import numpy as np
"""This function computes the modal parameter of a system
using using the PolyMAX method. The FRF input is a 3 dimensional matrix
of the output, input and corresponding frequency
Frequency value is a dictionary of a frequencies or output"""
#N - degree of freedom
N = list(range(Nmax, Nmin-1,-1))
#Find the maximum Order
Nmax = max(N)
# Find corresponding indices of frequency range
imin = Freq.index(min_freq)
imax = Freq.index(max_freq)
#converting all data to array
Freq = np.array(Freq)
#Frequency, Coh and FRF range
Freq = Freq[imin:imax]
FRF = FRF[:, imin:imax, :]
#Coh = Coh[:, imin:imax, :]
#Length of frequency-Nf, number of input-m, number of output-l
m, Nf, l = np.shape(FRF)
#compute the sample time
f_0 = min(Freq); f_N = max(Freq)
#Sampling Time
dt = 1/(2*(f_N-f_0))
#Define initial matrix for M, X, Y, for maximum model order 0 to N
M = np.zeros([Nmax+1,Nmax+1], dtype=complex)
X = np.zeros([Nf, Nmax+1], dtype=complex)
Y = np.zeros([Nf, (Nmax+1)*m], dtype=complex)
#Scalar weighting function
W_k = 1#np.array([1/freq_val if freq_val != 0.0 else 0.0 for freq_val in Freq])
#W_k = 100 #Coh[ms][i][ls]
#computing X
for j in range(Nf):
x = np.exp(1j * Freq[j] * dt * np.array([range(Nmax+1)])) * W_k#[j]
X[j,:] = x
R_sensor = np.real(np.matmul(np.transpose(X), X))
#compute M for all output
for ls in range(l):
for i in range(Nf):
Y[i,:] = -X[i,:] * np.transpose(FRF[:,i,ls])
T_sensor = np.real(np.matmul(np.transpose(Y), Y))
S_sensor = np.real(np.matmul(np.transpose(X), Y))
M_sensor = T_sensor - (np.transpose(S_sensor) @ np.linalg.inv(R_sensor) @ S_sensor)
M = M + M_sensor
M = 2*M
#Iterating for all model order
nat_freqs_P =[]
damp_ratio_P = []
order_P = []
for n in N:
A = M[0:n*m,0:n*m]
B = M[0:n*m, (n*m):]
alpha,_,_,_ = np.linalg.lstsq(-A, np.reshape(B, (-1,1)), rcond=None)
Im = np.identity(m)
alpha = np.concatenate((alpha, Im), axis = 0)
#creating the companion matrix
CM = np.eye(len(M),k = 1)
#remove the last row and join with alpha
CM = CM[0:-1,:]
CM = np.concatenate((CM, -np.transpose(alpha)), axis = 0)
poles, PF = np.linalg.eig(CM)
poles = np.log(poles)/dt
# Picking only poles with stable(negative) poles
poles = [pole for pole in poles if np.real(pole) < 0.0 and np.imag(pole) > 0.0
and np.abs(pole) <= max_freq and np.abs(pole) >= min_freq ]
# Find the natural frequency and damping factor of the system
nat_freq = np.abs(poles)
#Computing the Damping Ratio
dam_ratio = -np.real(poles) / nat_freq
#Natural frequency
nat_freqs_P.append(nat_freq)
#Damping Ratio
damp_ratio_P.append(dam_ratio)
#order from method
order_P.append(n)
M = M[:-1,:-1]
return nat_freqs_P, damp_ratio_P,order_P, FRF, Freq