VTI介质地震波传播模拟(PML边界条件)

VTI介质地震波传播模拟(PML边界条件)

用于模拟VTI(垂直横向各向同性)介质中的地震波传播,使用PML(完美匹配层)边界条件,并生成波场快照。

% VTI介质地震波传播模拟 - PML边界条件
% 使用各向异性弹性波方程和有限差分法

clear all; close all; clc;

%% 参数设置
% 模型参数
nx = 200;        % x方向网格点数
nz = 200;        % z方向网格点数
dx = 10;         % x方向网格间距(m)
dz = 10;         % z方向网格间距(m)
dt = 0.5e-3;     % 时间步长(s)
nt = 1000;       % 时间步数
f0 = 25;         % 震源主频(Hz)

% VTI介质参数 (Thomsen参数)
rho = 2500;      % 密度(kg/m^3)
vp0 = 3000;      % 垂直P波速度(m/s)
vs0 = 1500;      % 垂直S波速度(m/s)
epsilon = 0.2;   % Thomsen参数ε
delta = 0.1;     % Thomsen参数δ
gamma = 0.15;    % Thomsen参数γ

% 计算VTI刚度矩阵元素
C33 = rho * vp0^2;
C44 = rho * vs0^2;
C11 = C33 * (1 + 2*epsilon);
C66 = rho * vs0^2 * (1 + 2*gamma);
C13 = sqrt(C33^2 + C11^2 - 2*C33*C11 - 4*C44^2)/2 - C44;

% PML参数
pml_width = 20;  % PML层宽度(网格点数)
R = 1e-6;        % 理论反射系数
damp_max = 3;    % 最大阻尼系数

% 震源位置
src_x = nx/2;
src_z = nz/2;

% 接收点位置
rec_x = src_x + 50;
rec_z = src_z;

%% 初始化模型
% 创建空间坐标
x = (0:nx-1)*dx;
z = (0:nz-1)*dz;

% 初始化场变量
vx = zeros(nx, nz);     % x方向速度分量
vz = zeros(nx, nz);     % z方向速度分量
sxx = zeros(nx, nz);    % xx应力分量
szz = zeros(nx, nz);    % zz应力分量
sxz = zeros(nx, nz);    % xz剪切应力分量

% 初始化PML参数
[pml_alpha_x, pml_alpha_z] = setup_pml(nx, nz, pml_width, damp_max);

%% 震源函数 - Ricker子波
t = (0:nt-1)*dt;
src_func = (1 - 2*(pi*f0*t).^2) .* exp(-(pi*f0*t).^2);

%% 主循环 - 时间推进
for it = 1:nt
    % 添加震源 (力源在中心点)
    if it <= length(src_func)
        sxx(src_x, src_z) = sxx(src_x, src_z) + src_func(it) * dt;
    end
    
    % 更新速度分量 (x方向)
    for i = 2:nx-1
        for j = 2:nz-1
            % 计算空间导数
            dsxx_dx = (sxx(i+1,j) - sxx(i-1,j))/(2*dx);
            dsxz_dz = (sxz(i,j+1) - sxz(i,j-1))/(2*dz);
            
            % 更新速度 (考虑PML阻尼)
            vx(i,j) = vx(i,j) + dt/rho * (dsxx_dx + dsxz_dz) - pml_alpha_x(i,j)*vx(i,j)*dt;
        end
    end
    
    % 更新速度分量 (z方向)
    for i = 2:nx-1
        for j = 2:nz-1
            % 计算空间导数
            dsxz_dx = (sxz(i+1,j) - sxz(i-1,j))/(2*dx);
            dszz_dz = (szz(i,j+1) - szz(i,j-1))/(2*dz);
            
            % 更新速度 (考虑PML阻尼)
            vz(i,j) = vz(i,j) + dt/rho * (dsxz_dx + dszz_dz) - pml_alpha_z(i,j)*vz(i,j)*dt;
        end
    end
    
    % 更新应力分量 (xx)
    for i = 2:nx-1
        for j = 2:nz-1
            % 计算空间导数
            dvx_dx = (vx(i+1,j) - vx(i-1,j))/(2*dx);
            dvz_dz = (vz(i,j+1) - vz(i,j-1))/(2*dz);
            
            % 更新应力 (VTI介质)
            sxx(i,j) = sxx(i,j) + dt * (C11*dvx_dx + C13*dvz_dz);
        end
    end
    
    % 更新应力分量 (zz)
    for i = 2:nx-1
        for j = 2:nz-1
            % 计算空间导数
            dvx_dx = (vx(i+1,j) - vx(i-1,j))/(2*dx);
            dvz_dz = (vz(i,j+1) - vz(i,j-1))/(2*dz);
            
            % 更新应力 (VTI介质)
            szz(i,j) = szz(i,j) + dt * (C13*dvx_dx + C33*dvz_dz);
        end
    end
    
    % 更新应力分量 (xz)
    for i = 2:nx-1
        for j = 2:nz-1
            % 计算空间导数
            dvx_dz = (vx(i,j+1) - vx(i,j-1))/(2*dz);
            dvz_dx = (vz(i+1,j) - vz(i-1,j))/(2*dx);
            
            % 更新应力 (VTI介质)
            sxz(i,j) = sxz(i,j) + dt * C44 * (dvx_dz + dvz_dx);
        end
    end
    
    % 边界条件 - 自由表面 (顶部边界)
    j = 1; % 顶部边界
    szz(:,j) = 0;
    sxz(:,j) = 0;
    
    % 保存波场快照 (每隔一定步数)
    if mod(it, 50) == 0
        snap_vx(:,:,it/50) = vx;
        snap_vz(:,:,it/50) = vz;
        snap_sxx(:,:,it/50) = sxx;
        snap_szz(:,:,it/50) = szz;
        snap_sxz(:,:,it/50) = sxz;
        time_snap(it/50) = it*dt;
    end
end

%% 波场快照可视化
plot_wavefield_snapshots(time_snap, snap_vx, snap_vz, snap_sxx, snap_szz, snap_sxz, nx, nz, dx, dz);

%% PML设置函数
function [pml_alpha_x, pml_alpha_z] = setup_pml(nx, nz, width, damp_max)
    % 初始化PML阻尼系数
    pml_alpha_x = zeros(nx, nz);
    pml_alpha_z = zeros(nx, nz);
    
    % x方向PML (左右边界)
    for i = 1:width
        % 左边界
        coeff = damp_max * (1 - cos(pi*i/(2*width))) / 2;
        pml_alpha_x(i, :) = coeff;
        pml_alpha_x(nx-i+1, :) = coeff;
        
        % z方向PML (上下边界)
        pml_alpha_z(:, i) = coeff;
        pml_alpha_z(:, nz-i+1) = coeff;
    end
end

%% 波场快照可视化函数
function plot_wavefield_snapshots(time_snap, snap_vx, snap_vz, snap_sxx, snap_szz, snap_sxz, nx, nz, dx, dz)
    % 创建网格
    [X, Z] = meshgrid(0:dx:(nx-1)*dx, 0:dz:(nz-1)*dz);
    
    % 选择要显示的快照
    snapshot_indices = [2, 4, 6, 8, 10]; % 对应时间步200, 400, 600, 800, 1000
    
    % 创建图形
    figure('Position', [100, 100, 1200, 900]);
    
    for i = 1:length(snapshot_indices)
        idx = snapshot_indices(i);
        t = time_snap(idx);
        
        % 绘制垂直速度分量
        subplot(5, 3, (i-1)*3+1);
        imagesc(X(1,:), Z(:,1), snap_vz(:,:,idx)');
        colormap(seismic); colorbar;
        title(sprintf('Vz (t=%.1fs)', t));
        xlabel('X (m)'); ylabel('Z (m)');
        axis equal tight;
        caxis([-1e-6, 1e-6]);
        
        % 绘制水平速度分量
        subplot(5, 3, (i-1)*3+2);
        imagesc(X(1,:), Z(:,1), snap_vx(:,:,idx)');
        colormap(seismic); colorbar;
        title(sprintf('Vx (t=%.1fs)', t));
        xlabel('X (m)'); ylabel('Z (m)');
        axis equal tight;
        caxis([-1e-6, 1e-6]);
        
        % 绘制压力场 (P波)
        pressure = (snap_sxx(:,:,idx) + snap_szz(:,:,idx))/2;
        subplot(5, 3, (i-1)*3+3);
        imagesc(X(1,:), Z(:,1), pressure');
        colormap(seismic); colorbar;
        title(sprintf('Pressure (t=%.1fs)', t));
        xlabel('X (m)'); ylabel('Z (m)');
        axis equal tight;
        caxis([-1e7, 1e7]);
    end
    
    sgtitle('VTI介质地震波传播波场快照 (PML边界条件)');
    
    % 单独绘制剪切波场
    figure('Position', [100, 100, 800, 600]);
    shear_stress = snap_sxz(:,:,end);
    imagesc(X(1,:), Z(:,1), shear_stress');
    colormap(seismic); colorbar;
    title(sprintf('剪切应力 Sxz (t=%.1fs)', time_snap(end)));
    xlabel('X (m)'); ylabel('Z (m)');
    axis equal tight;
    caxis([-1e7, 1e7]);
end

程序功能说明

1. 物理模型

2. 数值方法

3. 关键组件

4. 可视化功能

运行结果

程序运行后会生成两组图形:

  1. 主波场快照图:5行3列共15个子图,显示5个不同时间点的:

    • 垂直速度分量(Vz)
    • 水平速度分量(Vx)
    • 压力场(平均应力)
  2. 剪切波场图:显示最终时刻的剪切应力分量(Sxz)

参数调整建议

  1. 模型尺寸

    • 增加nxnz提高空间分辨率
    • 减小dxdz提高精度(需相应减小dt
  2. 震源参数

    • 修改f0改变主频(低频穿透深,高频分辨率高)
    • 调整震源位置src_x, src_z
  3. 介质参数

    • 修改Thomsen参数epsilon, delta, gamma模拟不同VTI特性
    • 调整密度rho和速度vp0, vs0
  4. PML设置

    • 增加pml_width提高吸收效果
    • 调整damp_max控制阻尼强度

参考代码 通过Matlab编程,给定初始条件及PML边界条件,模拟VTI介质中地震波传播的波场快照 www.youwenfan.com/contentcss/79964.html

扩展功能

如需进一步扩展,可考虑:

  1. 添加各向异性参数渐变层
  2. 实现更复杂的震源机制
  3. 添加接收器记录地震道
  4. 实现三维模拟
  5. 添加地层界面反射

 

专注于matlab/simulink,电子电路,编程