%% Duhamel积分计算任意荷载下响应
clear;clc;close all;
%% 结构参数
m = 100e3; k = 20e6; xi = 0.05;
omega = sqrt(k/m);
omegad = omega*sqrt(1-xi^2);
dt = 0.01; t = 0:dt:10; nt = length(t);
%% 简谐荷载
F0 = 10e3; theta = 0.8*omega;
f = F0*sin(theta*t);
%% Duhamel积分
x = zeros(1,nt);
for i = 2:nt
tau = 0:dt:t(i);
h = 1/(m*omegad)*exp(-xi*omega*(t(i)-tau)).*sin(omegad*(t(i)-tau));
x(i) = trapz(tau, f(1:i).*h);
end
%% 解析解对比
beta = theta/omega;
Rd = 1/sqrt((1-beta^2)^2 + (2*xi*beta)^2);
xst = F0/k;
x_analytic = xst*Rd*sin(theta*t);
figure('Color','w');
plot(t,x,'b-',t,x_analytic,'r--','LineWidth',1.5);
xlabel('时间 t(s)'); ylabel('位移 x(m)');
legend('Duhamel积分数值解','解析解');
title('简谐荷载下位移时程'); grid on;
多自由度矩阵组装
MATLAB
质量矩阵、刚度矩阵、Rayleigh阻尼矩阵组装
%% 多自由度体系矩阵组装
clear;clc;close all;
n = 3;
m = [200e3; 200e3; 150e3];
k = [30e6; 25e6; 20e6];
xi1 = 0.05; xi2 = 0.05;
%% 集中质量矩阵
M = diag(m);
disp('质量矩阵 M:'); disp(M);
%% 剪切型刚度矩阵
K = zeros(n,n);
for i = 1:n
if i < n
K(i,i) = k(i) + k(i+1);
K(i,i+1) = -k(i+1);
K(i+1,i) = -k(i+1);
else
K(i,i) = k(i);
end
end
disp('刚度矩阵 K:'); disp(K);
%% Rayleigh阻尼矩阵
[V,D] = eig(K,M);
omega = sort(sqrt(diag(D)));
omega1 = omega(1); omega2 = omega(2);
alpha = 2*omega1*omega2*(xi2*omega1 - xi1*omega2)/(omega1^2 - omega2^2);
beta = 2*(xi1*omega1 - xi2*omega2)/(omega1^2 - omega2^2);
C = alpha*M + beta*K;
fprintf('alpha = %.4f, beta = %.6f\n',alpha,beta);
disp('阻尼矩阵 C:'); disp(C);
自振频率与振型计算
MATLAB
特征值求解、振型归一化、振型图绘制
%% 自振频率与振型计算
clear;clc;close all;
n = 3;
m = [200e3; 200e3; 150e3];
k = [30e6; 25e6; 20e6];
M = diag(m);
K = zeros(n,n);
for i = 1:n
if i < n
K(i,i) = k(i) + k(i+1);
K(i,i+1) = -k(i+1);
K(i+1,i) = -k(i+1);
else
K(i,i) = k(i);
end
end
%% 广义特征值求解
[V,D] = eig(K,M);
[omega, idx] = sort(sqrt(diag(D)));
V = V(:,idx);
f = omega/(2*pi); T = 2*pi./omega;
%% 振型归一化(最大位移为1)
for i = 1:n
V(:,i) = V(:,i)/max(abs(V(:,i)));
end
disp('各阶自振周期(s):'); disp(T');
disp('振型矩阵:'); disp(V);
%% 绘制振型图
figure('Color','w');
for i = 1:n
subplot(1,n,i);
plot([0;V(:,i)],0:n,'bo-','LineWidth',1.5,'MarkerFaceColor','b');
xlabel('位移'); ylabel('楼层');
title(['第',num2str(i),'阶振型 T=',num2str(T(i),'%.3f'),'s']);
grid on; axis equal;
end
sgtitle('结构振型图');
振型分解反应谱法
MATLAB
抗震规范反应谱计算、SRSS振型组合
%% 振型分解反应谱法计算地震作用
clear;clc;close all;
n = 3;
m = [200e3; 200e3; 150e3];
k = [30e6; 25e6; 20e6];
M = diag(m);
K = zeros(n,n);
for i = 1:n
if i < n
K(i,i) = k(i) + k(i+1);
K(i,i+1) = -k(i+1);
K(i+1,i) = -k(i+1);
else
K(i,i) = k(i);
end
end
[V,D] = eig(K,M);
[omega,idx] = sort(sqrt(diag(D))); V = V(:,idx);
T = 2*pi./omega;
%% 振型质量归一化
for i = 1:n
Mn = V(:,i)'*M*V(:,i);
V(:,i) = V(:,i)/sqrt(Mn);
end
%% 8度设防II类场地反应谱
alpha_max = 0.16; Tg = 0.35; gamma = 0.9; eta2 = 1.0;
alpha = zeros(n,1);
for i = 1:n
if T(i) < 0.1, alpha(i) = (0.45 + 5.5*T(i))*alpha_max;
elseif T(i) < Tg, alpha(i) = eta2*alpha_max;
elseif T(i) < 5*Tg, alpha(i) = (Tg/T(i))^gamma*eta2*alpha_max;
else, alpha(i) = (eta2*0.2^gamma - 0.02*(T(i)-5*Tg))*alpha_max;
end
end
%% 振型参与系数与地震作用
gamma_n = V'*M*ones(n,1);
F = zeros(n,n);
for j = 1:n
F(:,j) = alpha(j)*gamma_n(j)*M*V(:,j)*9.8;
end
%% 层剪力SRSS组合
V_mode = zeros(n,n);
for j = 1:n
V_mode(n,j) = F(n,j);
for i = n-1:-1:1
V_mode(i,j) = V_mode(i+1,j) + F(i,j);
end
end
V = sqrt(sum(V_mode.^2,2));
disp('各层地震剪力(kN):'); disp(V/1000);
中心差分法时程分析
MATLAB
显式逐步积分法时程计算
%% 中心差分法时程分析
clear;clc;close all;
n = 3;
m = [200e3;200e3;150e3]; k = [30e6;25e6;20e6]; xi=0.05;
M = diag(m); K=zeros(n,n);
for i=1:n
if i
Newmark-β法时程分析
MATLAB
隐式平均加速度法时程计算
%% Newmark-β法时程分析(平均加速度法)
clear;clc;close all;
n = 3;
m = [200e3;200e3;150e3]; k = [30e6;25e6;20e6]; xi=0.05;
M = diag(m); K=zeros(n,n);
for i=1:n
if i
双线性恢复力模型
MATLAB
双线性弹塑性恢复力滞回曲线计算
%% 双线性恢复力模型
clear;clc;close all;
k0 = 20e6; Fy = 100e3; alpha = 0.05;
uy = Fy/k0; k1 = alpha*k0;
t = 0:0.01:10;
u = 0.02*sin(2*pi*0.5*t);
nt = length(u);
F = zeros(1,nt);
F(1) = 0; u_last = 0; F_last = 0;
state = 0;
for i=2:nt
du = u(i) - u(i-1);
if state == 0
F_trial = F_last + k0*du;
if F_trial > Fy
state = 1; F(i) = Fy + k1*(u(i)-uy);
elseif F_trial < -Fy
state = -1; F(i) = -Fy + k1*(u(i)+uy);
else F(i) = F_trial; end
elseif state == 1
if du < 0
state = 0; F(i) = F_last + k0*du;
else F(i) = F_last + k1*du; end
else
if du > 0
state = 0; F(i) = F_last + k0*du;
else F(i) = F_last + k1*du; end
end
u_last = u(i); F_last = F(i);
end
figure('Color','w');
plot(u,F,'b-','LineWidth',1.5);
xlabel('位移 u(m)'); ylabel('恢复力 F(N)');
title('双线性恢复力滞回曲线');
grid on; axis equal;
弹塑性时程分析
MATLAB
双线性模型+Newmark法+牛顿迭代弹塑性时程
%% 弹塑性时程分析
clear;clc;close all;
m = 100e3; k0=20e6; xi=0.05; Fy=80e3; alpha=0.05;
omega = sqrt(k0/m); c = 2*xi*m*omega;
gamma=0.5; beta=0.25; dt=0.02; t=0:dt:10; nt=length(t);
u=zeros(1,nt);v=zeros(1,nt);a=zeros(1,nt);
a(1)=0; Fs=0; state=0; u_last=0; Fs_last=0;
P = zeros(1,nt); P(10) = 120e3;
for i=1:nt-1
u(i+1) = u(i);
for iter=1:20
du = u(i+1) - u_last;
if state==0
kt = k0; Fs_trial = Fs_last + kt*du;
if Fs_trial>Fy
state=1; Fs=Fy+alpha*k0*(u(i+1)-Fy/k0); kt=alpha*k0;
elseif Fs_trial<-Fy
state=-1; Fs=-Fy+alpha*k0*(u(i+1)+Fy/k0); kt=alpha*k0;
else Fs=Fs_trial; end
elseif state==1
kt=alpha*k0;
if du<0, state=0; kt=k0; Fs=Fs_last+kt*du;
else Fs=Fs_last+kt*du; end
else
kt=alpha*k0;
if du>0, state=0; kt=k0; Fs=Fs_last+kt*du;
else Fs=Fs_last+kt*du; end
end
a(i+1) = 1/(beta*dt^2)*(u(i+1)-u(i)) - 1/(beta*dt)*v(i) - (1/(2*beta)-1)*a(i);
v(i+1) = v(i) + dt*((1-gamma)*a(i)+gamma*a(i+1));
R = P(i+1) - m*a(i+1) - c*v(i+1) - Fs;
K_hat = kt + gamma/(beta*dt)*c + 1/(beta*dt^2)*m;
du_iter = K_hat\R;
u(i+1) = u(i+1) + du_iter;
if norm(du_iter)<1e-8, break; end
end
u_last=u(i+1); Fs_last=Fs;
end
figure('Color','w');
plot(t,u,'b-','LineWidth',1);
xlabel('时间(s)');ylabel('位移(m)');
title('弹塑性时程分析位移时程');grid on;
Newmark-β法通用函数
MATLAB
多自由度体系地震响应计算通用函数
function [u, v, a] = newmark_beta(M, K, C, P, dt, beta, gamma)
% Newmark-β法求解结构动力响应
% 输入:M-质量矩阵 K-刚度矩阵 C-阻尼矩阵
% P-荷载向量(nt*n列,每列对应一个时刻) dt-时间步长
% beta, gamma-积分参数,默认beta=0.25,gamma=0.5(平均加速度法)
if nargin<7, gamma=0.5; end
if nargin<6, beta=0.25; end
n = size(M,1);
nt = size(P,2);
u = zeros(n,nt); v = zeros(n,nt); a = zeros(n,nt);
% 初始加速度
a(:,1) = M\(P(:,1) - C*v(:,1) - K*u(:,1));
% 有效刚度矩阵
K_hat = K + gamma/(beta*dt)*C + 1/(beta*dt^2)*M;
for i = 1:nt-1
% 有效荷载
P_hat = P(:,i+1) + M*(1/(beta*dt^2)*u(:,i) + 1/(beta*dt)*v(:,i) + (1/(2*beta)-1)*a(:,i)) ...
+ C*(gamma/(beta*dt)*u(:,i) + (gamma/beta-1)*v(:,i) + dt*(gamma/(2*beta)-1)*a(:,i));
u(:,i+1) = K_hat\P_hat;
a(:,i+1) = 1/(beta*dt^2)*(u(:,i+1)-u(:,i)) - 1/(beta*dt)*v(:,i) - (1/(2*beta)-1)*a(:,i);
v(:,i+1) = v(:,i) + dt*((1-gamma)*a(:,i) + gamma*a(:,i+1));
end
end