模拟山体滑坡

模拟山体滑坡:利用简单的物理模型和 matplotlib,模拟山体上不同质量的物体在一定坡度下的滑动过程,展示滑坡的形成。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from scipy.ndimage import gaussian_filter


class LandslideSimulator:
    def __init__(self):
        self.grid_size = (200, 200)
        self.dx = 1.0
        self.dt = 0.1
        self.g = 9.81

        self.density = 1600.0
        self.cohesion = 5000.0
        self.friction_angle = 30.0
        self.pore_pressure = 0.3

        self.initialize_terrain()

        self.velocity = np.zeros(self.grid_size + (2,))
        self.stress = np.zeros(self.grid_size + (2, 2))

    def initialize_terrain(self):
        x = np.linspace(0, 20, self.grid_size[1])
        y = np.linspace(0, 20, self.grid_size[0])
        X, Y = np.meshgrid(x, y)
        self.height = 15 - 0.4 * X + 2 * np.sin(0.5 * X)

        noise = np.random.normal(0, 0.5, self.grid_size)
        self.height += gaussian_filter(noise, sigma=2)

        self.strength = np.ones(self.grid_size) * self.cohesion
        weakness_zone = (X > 8) & (X < 12) & (Y > 5) & (Y < 15)
        self.strength[weakness_zone] *= 0.2

        self.mask = np.ones(self.grid_size, dtype=bool)
        self.original_height = self.height.copy()

    def calculate_stress(self):
        depth = self.original_height - self.height
        # 检查深度值,避免数值过大
        depth = np.clip(depth, 0, 10)
        sigma_z = self.density * self.g * depth

        tau_max = (sigma_z * (1 - self.pore_pressure) *
                   np.tan(np.deg2rad(self.friction_angle)) + self.strength)

        grad = np.gradient(self.height, self.dx)
        tau_x = -self.density * self.g * grad[0]
        tau_y = -self.density * self.g * grad[1]

        self.stress[..., 0, 0] = tau_x
        self.stress[..., 1, 1] = tau_y
        self.stress[..., 0, 1] = self.stress[..., 1, 0] = 0.5 * (tau_x + tau_y)

        # 修正后的计算表达式(原71行)
        tau_magnitude = np.sqrt(tau_x ** 2 + tau_y ** 2)
        self.failure_mask = tau_magnitude > tau_max

    def update_velocity(self):
        body_force = np.zeros_like(self.velocity)
        body_force[..., 1] = self.density * self.g

        stress_grad = np.gradient(self.stress, self.dx, axis=(0, 1))
        total_force = body_force - (stress_grad[0][..., 0] + stress_grad[1][..., 1])

        # 检查总力值,避免数值过大
        total_force = np.clip(total_force, -1e6, 1e6)
        acceleration = total_force / self.density
        self.velocity += acceleration * self.dt
        self.velocity *= 0.98

    def update_height(self):
        flux = np.zeros_like(self.height)

        vx = self.velocity[..., 0]
        height_diff_x = self.height[:, :-2] - self.height[:, 2:]
        # 检查高度差,避免数值过大
        height_diff_x = np.clip(height_diff_x, -1e6, 1e6)
        flux[:, 1:-1] += vx[:, 1:-1] * height_diff_x / (2 * self.dx)

        vy = self.velocity[..., 1]
        height_diff_y = self.height[:-2, :] - self.height[2:, :]
        # 检查高度差,避免数值过大
        height_diff_y = np.clip(height_diff_y, -1e6, 1e6)
        flux[1:-1, :] += vy[1:-1, :] * height_diff_y / (2 * self.dx)

        # 检查通量值,避免数值过大
        flux = np.clip(flux, -1e6, 1e6)
        self.height += flux * self.dt
        self.height[self.failure_mask] -= 0.1 * self.dt * self.velocity[self.failure_mask, 1]

        self.height[:, 0] = self.original_height[:, 0]
        self.height[0, :] = self.original_height[0, :]

    def step(self):
        self.calculate_stress()
        self.update_velocity()
        self.update_height()


# 初始化模拟器和图形
sim = LandslideSimulator()
fig = plt.figure(figsize=(10, 5))
ax1 = fig.add_subplot(121, projection='3d')
ax2 = fig.add_subplot(122)

x = np.linspace(0, 20, sim.grid_size[1])
y = np.linspace(0, 20, sim.grid_size[0])
X, Y = np.meshgrid(x, y)


def update(frame):
    sim.step()
    ax1.cla()
    ax2.cla()

    ax1.plot_surface(X, Y, sim.height, cmap='terrain', alpha=0.8)
    ax1.set_zlim(0, 20)
    ax1.set_title('3D opographic Evolution')

    skip = 5
    ax2.quiver(X[::skip, ::skip], Y[::skip, ::skip],
               sim.velocity[::skip, ::skip, 0],
               sim.velocity[::skip, ::skip, 1],
               scale=50, color='red')
    ax2.imshow(sim.height, extent=[0, 20, 0, 20], cmap='terrain', origin='lower')

    return ax1, ax2


ani = FuncAnimation(fig, update, frames=200, interval=50, blit=False)
plt.show()
Python山体滑坡算法库是一个用于模拟和分析山体滑坡的开源工具。它提供了各种算法和模型,用于预测和评估山体滑坡的发生概率和规模。这个库可以帮助工程师、地质学家和相关领域的专业人员更好地了解和管理山地地质灾害。 该算法库主要包括以下几个方面的功能: 1. 数值模型:提供了一些常用的数值模型,如格子模型和连续介质模型,用于模拟和预测山体滑坡的运动和发展过程。这些模型基于物理规律和地质特征,可以更准确地预测滑坡的位置、速度和规模。 2. 数据分析:提供了数据处理和分析的功能,可以对地质数据进行统计分析和可视化展示。用户可以通过这些功能分析地质条件、土壤稳定性和降雨情况等因素对滑坡发生的影响。 3. 参数优化:提供了参数优化的方法,用户可以通过调整模型的参数来改善预测结果的准确性。这些优化工具可以帮助用户找到最佳的参数组合,从而提高模型的性能和可靠性。 4. 风险评估:提供了风险评估的功能,可以通过分析山体滑坡的潜在危害和影响来评估风险水平。这些评估结果可以帮助决策者采取相应的防灾措施和应急预案,从而减少山地地质灾害的损失。 总之,Python山体滑坡算法库是一个功能强大的工具,它可以帮助研究人员和工程师更好地理解和管理山地滑坡风险。它的开源性质也使得用户可以根据自己的需求进行二次开发和定制,满足不同领域的特定需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值