Optimization Eigenvalue problem Stiffness matrix
조회 수: 12 (최근 30일)
이전 댓글 표시
I have a eigenvalue problem of the form (K - w²*M)*R = 0, where:
Please see a reference question. They do not use non-diagonal stiffness matrix
- K is a 3x3 diagonal matrix with unknown values,
- M is a known 3x3 matrix,
- w² represents the eigenvalues (typically denoted as lambda) and is related to the known frequencies f (where w = 2pif),
- R are the corresponding eigenvectors.
My goal is to determine the diagonal values of K that minimize the difference between my exact frequency values (f_exact) and the calculated frequency values (f_calc), which are computed iteratively.
I’ve attempted to use lsqnonlin for optimization, but the calculated frequencies (f_calc) are significantly off from my target values (f_exact). Does anyone have suggestions on how to improve the optimization approach?
Here is the code I used:
% Marina Krauze Thomaz
% REF: https://www.mathworks.com/matlabcentral/answers/2004382-eigenvalue-problem-optimized-with-lqsnonlin
% Given data
m1_kip_s2_ft = 1035;
m2_kip_s2_ft = 628;
m3_kip_s2_ft = 591;
% m1 = 1035;
% m2 = 628;
% m3 = 591;
M = diag([m1_kip_s2_ft, m2_kip_s2_ft, m3_kip_s2_ft]); % Mass matrix
T_wanted1_s = 5.2;
T_wanted2_s = 4.0;
T_wanted3_s = 1.17;
T_wanted_s = [T_wanted1_s; T_wanted2_s; T_wanted3_s]; % Target periods
f1_Hz = 1/T_wanted1_s;
f2_Hz = 1/T_wanted2_s;
f3_Hz = 1/T_wanted3_s;
f_exact_Hz = [f1_Hz, f2_Hz, f3_Hz];
% Improved Initial Guess for Stiffness Matrix (Non-Diagonal Form)
% Use a heuristic guess for k1, k2, and k3 based on mass and frequency
k1_guess = (1); % Guess
k2_guess = (1); % Guess
k3_guess = (1); % Guess
% Combine into initial guess vector [k1, k2, k3]
K_guess_kip_ft = [k1_guess + k2_guess, -k2_guess, 0;
-k2_guess, k2_guess + k3_guess, -k3_guess;
0, -k3_guess, k3_guess];
% Bounds for K
LB = [1, 1, 1];
UB = [1e16, 1e16, 1e16];
% Define bounds and flatten them for optimization (vectorize)
LB_vec = LB(:);
UB_vec = UB(:);
K_guess_vec = K_guess_kip_ft(:); % Vectorize the initial guess matrix
% Optimization options with relaxed tolerances
options = optimoptions('lsqnonlin', 'FunctionTolerance', 1e-8, 'StepTolerance', 1e-8, ...
'OptimalityTolerance', 1e-6, 'MaxFunEvals', inf, 'MaxIterations', 5000);
% Perform optimization
[K_opt_vec,~,res] = lsqnonlin(@(K) obj_function_reshaped_matrix(K, M, f_exact_Hz), K_guess_vec, LB_vec, UB_vec, options);
%% Reshape the optimized vector back into a matrix
K_opt = [K_opt_vec(1) + K_opt_vec(2), -K_opt_vec(2), 0;
-K_opt_vec(2), K_opt_vec(2) + K_opt_vec(3), -K_opt_vec(3);
0, -K_opt_vec(3), K_opt_vec(3)];
% Check the optimized stiffness matrix
disp('Optimized Stiffness Matrix (K):');
disp(K_opt);
% Solve eigenvalue problem with optimized K
[R, L] = eig(K_opt, M);
f_calc_Hz = (diag(sqrt(L) ./ (2 * pi)).'); % Do not sort to preserve order
T_calc_s = 1 ./f_calc_Hz; % Periods as a row vector
%% Error
% Calculate the squared error between target and calculated periods
error_squared = (T_wanted_s - T_calc_s.').^2; %Transpose T_calc_s
% Display calculated periods and error
disp('Calculated periods (T_calc_s):');
disp(T_calc_s);
disp('Squared error between target and calculated periods:');
disp(error_squared);
% Check the optimized stiffness matrix
disp('Optimized Stiffness Matrix (K):');
disp(K_opt);
%% Objective function definition
function diff = obj_function_reshaped_matrix(K_vec, M, f_exact)
% Stiffness values
k1 = K_vec(1);
k2 = K_vec(2);
k3 = K_vec(3);
% Construct stiffness matrix
K_mat = [k1 + k2, -k2, 0;
-k2, k2 + k3, -k3;
0, -k3, k3];
% Solve eigenvalue problem
[~, L] = eig(K_mat, M);
% Calculate natural frequencies from eigenvalues
omega_calc = sqrt(diag(L)); % Rad/s
f_calc_Hz = omega_calc / (2 * pi); % Convert to Hz
% Return squared frequency differences (to minimize)
diff = (f_calc_Hz - f_exact).^2; % Use squared difference
end
댓글 수: 0
답변 (2개)
Torsten
2024년 10월 22일 9:48
편집: Torsten
2024년 10월 22일 10:04
Should be
% Perform optimization
[K_opt_vec,~,res] = lsqnonlin(@(K) obj_function_reshaped_matrix(K, M, f_exact_Hz), [k1_guess,k2_guess,k3_guess], LB_vec, UB_vec, options);
instead of
% Perform optimization
[K_opt_vec,~,res] = lsqnonlin(@(K) obj_function_reshaped_matrix(K, M, f_exact_Hz), K_guess_vec, LB_vec, UB_vec, options);
and
% Return squared frequency differences (to minimize)
diff = f_calc_Hz - f_exact; % Use squared difference
instead of
% Return squared frequency differences (to minimize)
diff = (f_calc_Hz - f_exact).^2; % Use squared difference
(squaring is done internally by "lsqnonlin").
And I think it's necessary to compare sort(f_calc_Hz) with sort( f_exact), thus
diff = sort(f_calc_Hz) - sort(f_exact); % Use squared difference
댓글 수: 0
Sam Chak
2024년 10월 22일 16:43
Hi @Marina
The problem has two parts. I have solved only the first part for you, which is to determine the characteristic polynomial that yields the desired natural frequencies. You need to solve the second part of the problem, which involves finding the stiffness matrix that produces the target characteristic polynomial. However, my preliminary analysis indicates that there is no real-valued solution. My analysis could be inaccurate; please double-check this.
format long g
%% Desired natural frequencies
m1_kip_s2_ft= 1035;
m2_kip_s2_ft= 628;
m3_kip_s2_ft= 591;
M = diag([m1_kip_s2_ft, m2_kip_s2_ft, m3_kip_s2_ft]); % Mass matrix
T_wanted1_s = 5.2;
T_wanted2_s = 4.0;
T_wanted3_s = 1.17;
T_wanted_s = [T_wanted1_s; T_wanted2_s; T_wanted3_s]; % Target periods
f1_Hz = 1/T_wanted1_s;
f2_Hz = 1/T_wanted2_s;
f3_Hz = 1/T_wanted3_s;
f = [f1_Hz; f2_Hz; f3_Hz] % <-- Desired natural frequencies
%% Desired Characteristic Polynomial, CP
omega = 2*pi*f;
myRoots = omega.^2;
% r1 = 1.46000065104872
% r2 = 2.46740110027234
% r3 = 28.8395190330612
CP = poly(myRoots) % <-- target Characteristic Polynomial
%% Testing results (according to OP's code)
sol = roots(CP);
omega_calc = sqrt(sol); % rad/s
f_calc_Hz = sort(omega_calc/(2*pi))
%% Part 2: Need to solve for {k1, k2, k3} to satisfy CP
syms k1 k2 k3 real positive
K = [k1 + k2, -k2, 0;
-k2, k2 + k3, -k3;
0, -k3, k3];
M = diag([m1_kip_s2_ft, m2_kip_s2_ft, m3_kip_s2_ft]); % Mass matrix
MK = M\K;
cp = charpoly(MK)
%% One of six complex-valued solution sets
k1 = 2031.99 - 2061.74i;
k2 = 1089.46 + 1192.27i;
k3 = 8530.08 - 322.27i;
K_mat = [k1 + k2, -k2, 0;
-k2, k2 + k3, -k3;
0, -k3, k3];
[~, L] = eig(K_mat, M);
%% Calculate natural frequencies from eigenvalues
omega_calc = sqrt(diag(L)); % rad/s
f_calc_Hz = omega_calc/(2*pi) % Convert to Hz
댓글 수: 0
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!