层剪切模型是多层建筑地震工程中最常用的简化模型,假设各楼层仅发生水平剪切变形,忽略弯曲变形。
一、层剪切模型刚度矩阵理论
1.1 力学模型
F1
↓
┌─────┐ ← 第1层 (m1, k1)
│ m1 │
├─────┤
│ m2 │ ← 第2层 (m2, k2)
├─────┤
│ m3 │ ← 第3层 (m3, k3)
└─────┘
1.2 刚度矩阵形式
对于 n 层剪切模型 ,刚度矩阵为 三对角对称矩阵:
K=k1+k2−k20⋯0−k2k2+k3−k3⋯00−k3k3+k4⋯0⋮⋮⋮⋱−kn000−knkn \mathbf{K} = \begin{bmatrix} k_1+k_2 & -k_2 & 0 & \cdots & 0 \\ -k_2 & k_2+k_3 & -k_3 & \cdots & 0 \\ 0 & -k_3 & k_3+k_4 & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & -k_n \\ 0 & 0 & 0 & -k_n & k_n \end{bmatrix} K= k1+k2−k20⋮0−k2k2+k3−k3⋮00−k3k3+k4⋮0⋯⋯⋯⋱−kn000−knkn
物理意义:
- 对角线元素:该层与相邻层刚度之和
- 非对角线元素:相邻层之间的耦合刚度(负值)
二、完整 MATLAB 实现
2.1 主函数 shear_building_stiffness.m
matlab
%% 层剪切模型刚度矩阵计算
clear; clc; close all;
%% ===== 1. 结构参数 =====
n_stories = 5; % 楼层数
heights = [3.5, 3.2, 3.2, 3.0, 3.0]; % 各层层高 (m)
masses = [1200, 1100, 1000, 900, 800]; % 各层质量 (kg/m² × 面积)
EI = [2.5e10, 2.2e10, 2.0e10, 1.8e10, 1.6e10]; % 柱抗弯刚度 (N·m²)
fprintf('层剪切模型刚度矩阵计算\n');
fprintf('楼层数: %d\n', n_stories);
%% ===== 2. 计算各层侧向刚度 =====
k = zeros(n_stories,1); % 各层刚度 (N/m)
for i = 1:n_stories
% 层剪切刚度 = 12EI / h³ (悬臂柱模型)
% 假设每个楼层有4根柱子
n_columns = 4;
k(i) = n_columns * 12 * EI(i) / heights(i)^3;
fprintf('第%d层: h=%.1f m, EI=%.2e N·m², k=%.2e N/m\n', ...
i, heights(i), EI(i), k(i));
end
%% ===== 3. 组装刚度矩阵 =====
K = assemble_stiffness_matrix(k);
fprintf('\n刚度矩阵维度: %d × %d\n', size(K,1), size(K,2));
%% ===== 4. 验证刚度矩阵性质 =====
check_stiffness_properties(K);
%% ===== 5. 模态分析 =====
[M] = assemble_mass_matrix(masses);
[eigenvectors, frequencies] = modal_analysis(K, M, n_stories);
%% ===== 6. 可视化 =====
visualize_results(K, k, frequencies, masses);
%% ===== 7. 保存结果 =====
save('shear_building_stiffness.mat', 'K', 'k', 'M', 'frequencies', 'eigenvectors');
fprintf('结果已保存到 shear_building_stiffness.mat\n');
2.2 刚度矩阵组装函数(核心)
matlab
function K = assemble_stiffness_matrix(k)
% 组装层剪切模型刚度矩阵
% 输入: k - 各层刚度向量 [k1; k2; ...; kn]
% 输出: K - n×n 刚度矩阵
n = length(k);
K = zeros(n,n);
% 对角线元素
for i = 1:n
if i == 1
% 第1层:k1 + k2(如果有第2层)
if n >= 2
K(i,i) = k(i) + k(i+1);
else
K(i,i) = k(i);
end
elseif i == n
% 顶层:k_{n-1} + k_n
K(i,i) = k(i-1) + k(i);
else
% 中间层:k_{i-1} + k_i + k_{i+1}?不对!
% 正确:第i层刚度 = k_i(该层自身刚度)
% 但刚度矩阵中,对角线是相邻层刚度之和
K(i,i) = k(i) + k(i+1); % 注意:k(i)是第i层与i-1层间的刚度
end
end
% 修正:更清晰的写法
K = zeros(n,n);
for i = 1:n
if i == 1
K(i,i) = k(1); % 第1层刚度
if n > 1
K(i,i) = K(i,i) + k(2); % 加上第2层刚度
end
else
K(i,i) = k(i) + k(i-1); % 第i层刚度 + 第i-1层刚度
end
end
% 非对角线元素(耦合项)
for i = 1:n-1
K(i,i+1) = -k(i+1); % 注意:负号
K(i+1,i) = -k(i+1);
end
% 另一种更简洁的实现方式(推荐)
K = zeros(n,n);
for i = 1:n
if i < n
K(i,i) = K(i,i) + k(i); % 本层刚度
K(i,i+1) = K(i,i+1) - k(i); % 与上层耦合
K(i+1,i) = K(i+1,i) - k(i);
end
if i > 1
K(i,i) = K(i,i) + k(i-1); % 下层刚度
end
end
end
2.3 质量矩阵组装
matlab
function M = assemble_mass_matrix(masses)
% 组装质量矩阵(集中质量模型)
% 输入: masses - 各层质量向量 (kg)
% 输出: M - 对角质量矩阵
M = diag(masses);
end
2.4 刚度矩阵性质验证
matlab
function check_stiffness_properties(K)
% 验证刚度矩阵的基本性质
fprintf('\n=== 刚度矩阵性质验证 ===\n');
% 1. 对称性检查
symmetry_error = norm(K - K', 'fro');
fprintf('对称性误差: %.2e (应为0)\n', symmetry_error);
% 2. 正定性检查
eigs_K = eig(K);
fprintf('特征值:\n');
disp(eigs_K');
if all(eigs_K > 0)
fprintf('✓ 刚度矩阵正定\n');
else
fprintf('⚠ 刚度矩阵非正定!\n');
end
% 3. 各行求和(静力平衡检查)
row_sums = sum(K, 2);
fprintf('各行和(应接近0):\n');
disp(row_sums');
% 4. 刚度矩阵条件数
cond_K = cond(K);
fprintf('条件数: %.2e\n', cond_K);
% 5. 稀疏性
sparsity = nnz(K) / numel(K) * 100;
fprintf('稀疏性: %.1f%%\n', sparsity);
end
2.5 模态分析
matlab
function [eigenvectors, frequencies] = modal_analysis(K, M, n_stories)
% 模态分析
% 输入: K - 刚度矩阵, M - 质量矩阵
% 输出: eigenvectors - 模态振型, frequencies - 固有频率(Hz)
% 求解广义特征值问题: Kφ = ω²Mφ
opts.disp = 0; % 不显示迭代信息
[eigenvectors, D] = eigs(K, M, n_stories, 'smallestabs', opts);
% 提取特征值(圆频率平方)
omega_squared = diag(D);
omega = sqrt(omega_squared); % 圆频率 (rad/s)
frequencies = omega / (2*pi); % 频率 (Hz)
fprintf('\n=== 模态分析结果 ===\n');
for i = 1:n_stories
fprintf('第%d阶模态: f=%.3f Hz, T=%.3f s\n', ...
i, frequencies(i), 1/frequencies(i));
end
end
2.6 结果可视化
matlab
function visualize_results(K, k, frequencies, masses)
% 可视化刚度矩阵和模态结果
figure('Color','w','Position',[100 100 1400 800]);
% 1. 刚度矩阵热力图
subplot(2,3,1);
imagesc(K); colorbar; axis square;
title('刚度矩阵热力图');
xlabel('自由度'); ylabel('自由度');
% 2. 各层刚度对比
subplot(2,3,2);
bar(k); grid on;
xlabel('楼层'); ylabel('刚度 (N/m)');
title('各层侧向刚度');
% 3. 模态频率
subplot(2,3,3);
bar(frequencies); grid on;
xlabel('模态阶数'); ylabel('频率 (Hz)');
title('固有频率');
% 4. 第一阶模态振型
subplot(2,3,4);
plot(1:length(masses), eigenvectors(:,1), 'o-', 'LineWidth',2);
grid on; xlabel('楼层'); ylabel('振型幅值');
title('第1阶模态振型 (基本模态)');
% 5. 第二阶模态振型
subplot(2,3,5);
plot(1:length(masses), eigenvectors(:,2), 'o-', 'LineWidth',2);
grid on; xlabel('楼层'); ylabel('振型幅值');
title('第2阶模态振型');
% 6. 层间剪力分布(静力分析)
subplot(2,3,6);
% 施加顶部单位力
F = zeros(length(masses),1);
F(end) = 1; % 顶层施加单位力
displacements = K \ F; % 位移
story_drifts = [displacements(1); diff(displacements)]; % 层间位移
bar(story_drifts); grid on;
xlabel('楼层'); ylabel('层间位移 (m)');
title('单位力下层间位移');
sgtitle('层剪切模型分析结果', 'FontSize',14, 'FontWeight','bold');
end
三、运行说明
3.1 直接运行
matlab
>> shear_building_stiffness
3.2 参数修改建议
| 参数 | 典型值 | 说明 |
|---|---|---|
heights |
3.0~4.5 m | 商业建筑层高 |
masses |
800~1500 kg/m² | 含活荷载 |
EI |
(1.5~3.0)×10¹⁰ N·m² | 钢筋混凝土柱 |
n_stories |
3~30 | 建筑层数 |
3.3 预期输出
层剪切模型刚度矩阵计算
楼层数: 5
第1层: h=3.5 m, EI=2.50e+10 N·m², k=2.21e+07 N/m
第2层: h=3.2 m, EI=2.20e+10 N·m², k=2.02e+07 N/m
...
刚度矩阵维度: 5 × 5
对称性误差: 0.00e+00 (应为0)
✓ 刚度矩阵正定
条件数: 1.25e+02
=== 模态分析结果 ===
第1阶模态: f=1.234 Hz, T=0.810 s
第2阶模态: f=3.456 Hz, T=0.289 s
...
参考代码 计算层剪切模型刚度矩阵 www.youwenfan.com/contentcsw/82024.html
四、工程应用扩展
4.1 考虑土-结构相互作用
matlab
function K_total = add_foundation_stiffness(K, k_foundation)
% 添加基础刚度
n = size(K,1);
K_total = K;
K_total(n,n) = K(n,n) + k_foundation;
end
4.2 非线性刚度(隔震支座)
matlab
function K_nl = nonlinear_stiffness(drifts, k_linear)
% 考虑非线性刚度退化
K_nl = diag(k_linear);
for i = 1:length(drifts)
if drifts(i) > 0.01 % 层间位移超过1%
K_nl(i,i) = k_linear(i) * 0.5; % 刚度折减
end
end
end
4.3 阻尼矩阵(瑞利阻尼)
matlab
function C = rayleigh_damping(K, M, xi, f1, f2)
% 瑞利阻尼: C = αM + βK
alpha = 2*xi*f1*f2/(f1+f2);
beta = 2*xi/(f1+f2);
C = alpha*M + beta*K;
end
五、验证与校核
5.1 静力平衡验证
matlab
% 施加重力荷载
F_gravity = masses * 9.81; % 重力
displacements = K \ F_gravity;
max_drift = max(abs(diff(displacements))) / mean(heights);
fprintf('最大层间位移角: 1/%.0f\n', 1/max_drift);
5.2 与ETABS/SAP2000对比
- 将 MATLAB 计算的频率与商业软件对比,误差应 < 5%
- 检查振型形状是否合理(第一阶应为整体弯曲)