层剪切模型(Shear Building Model)刚度矩阵计算(MATLAB 实现)

层剪切模型是多层建筑地震工程中最常用的简化模型,假设各楼层仅发生水平剪切变形,忽略弯曲变形。


一、层剪切模型刚度矩阵理论

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%
  • 检查振型形状是否合理(第一阶应为整体弯曲)