You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在2D热方程求解中设置对角线热源及迭代终止条件?

解决方案:修改2D热方程模拟的热源形态与迭代停止条件

一、定义对角线/曲线形态的热源

1. 核心思路

替代原代码中硬编码的矩形/直线热源,通过自定义判断函数识别每个网格点(i,j)是否属于目标热源区域,可灵活实现对角线、圆形、抛物线等任意形态的热源。

2. 具体实现

(1)对角线热源示例

定义一条从(10,10)到(40,40)的3像素宽粗对角线:

def is_diagonal_source(i, j):
    # abs(i-j)<=2控制对角线厚度,10<=i<=40限制对角线范围
    return abs(i - j) <= 2 and 10 <= i <= 40 and 10 <= j <= 40

(2)曲线热源示例(圆形)

定义圆心在(25,25)、半径10的圆形热源:

def is_circle_source(i, j):
    center_x, center_y = 25, 25
    radius = 10
    # 利用圆的方程判断点是否在圆内
    return (i - center_x)**2 + (j - center_y)**2 <= radius**2

(3)将热源应用到模拟中

替换原代码的边界条件设置逻辑,遍历所有网格点标记热源:

# 初始化初始温度场
u_initial = 0.0
source_temp = 100.0
u0 = np.full((plate_length, plate_length), u_initial)

# 标记热源区域
for i in range(plate_length):
    for j in range(plate_length):
        # 可同时启用多个热源
        if is_diagonal_source(i, j) or is_circle_source(i, j):
            u0[i, j] = source_temp

同时在迭代计算时,跳过热源点的温度更新(保持热源温度恒定):

if is_diagonal_source(i,j) or is_circle_source(i,j):
    continue

二、修改迭代逻辑:温度达到最大值时自动停止

1. 核心思路

放弃固定迭代次数,改为动态循环:每次迭代后检查平板区域的最高温度是否接近热源温度(如100.0),达到阈值则停止;同时设置最大迭代次数作为兜底,避免无限循环。

2. 具体实现

(1)动态存储温度场

不再预分配固定大小的数组,改用列表存储每一步的温度场:

# 初始化温度场列表
u = []
u.append(u0)  # 添加初始状态

max_temp_target = source_temp
tolerance = 1e-3  # 浮点精度容忍度
max_iter_fallback = 500  # 最大迭代次数兜底
current_iter = 0

(2)迭代循环与停止条件

while current_iter < max_iter_fallback:
    u_prev = u[-1]
    u_next = u_prev.copy()
    
    # 更新非热源区域的温度
    for i in range(1, plate_length-1):
        for j in range(1, plate_length-1):
            if is_diagonal_source(i,j) or is_circle_source(i,j):
                continue
            u_next[i,j] = gamma * (u_prev[i+1][j] + u_prev[i-1][j] + u_prev[i][j+1] + u_prev[i][j-1] - 4*u_prev[i][j]) + u_prev[i][j]
    
    u.append(u_next)
    current_iter += 1
    
    # 检查停止条件
    current_max_temp = np.max(u_next)
    if abs(current_max_temp - max_temp_target) < tolerance:
        print(f"模拟自动停止:迭代次数={current_iter},当前最高温度={current_max_temp:.3f}")
        break

(3)更新动画生成逻辑

动画帧数改为实际迭代次数(即列表u的长度):

def animate(k):
    plotheatmap(u[k], k)

anim = animation.FuncAnimation(plt.figure(), animate, interval=1, frames=len(u), repeat=False)
anim.save("heat_equation_solution.gif")

完整修改后的代码

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

print("2D heat equation solver")

plate_length = 50
alpha = 2
delta_x = 1
delta_t = (delta_x ** 2)/(4 * alpha)
gamma = (alpha * delta_t) / (delta_x ** 2)

# 定义热源判断函数
def is_diagonal_source(i, j):
    return abs(i - j) <= 2 and 10 <= i <= 40 and 10 <= j <= 40

def is_circle_source(i, j):
    center_x, center_y = 25, 25
    radius = 10
    return (i - center_x)**2 + (j - center_y)**2 <= radius**2

# 初始化初始温度场
u_initial = 0.0
source_temp = 100.0
u0 = np.full((plate_length, plate_length), u_initial)

# 设置热源区域
for i in range(plate_length):
    for j in range(plate_length):
        if is_diagonal_source(i, j):
            u0[i, j] = source_temp

# 动态存储温度场
u = []
u.append(u0)

max_temp_target = source_temp
tolerance = 1e-3
max_iter_fallback = 500
current_iter = 0

# 迭代计算
while current_iter < max_iter_fallback:
    u_prev = u[-1]
    u_next = u_prev.copy()
    
    for i in range(1, plate_length-1):
        for j in range(1, plate_length-1):
            if is_diagonal_source(i,j):
                continue
            u_next[i,j] = gamma * (u_prev[i+1][j] + u_prev[i-1][j] + u_prev[i][j+1] + u_prev[i][j-1] - 4*u_prev[i][j]) + u_prev[i][j]
    
    u.append(u_next)
    current_iter += 1
    
    current_max = np.max(u_next)
    if abs(current_max - max_temp_target) < tolerance:
        print(f"Stopped at iteration {current_iter}, max temp: {current_max:.3f}")
        break

# 绘图函数
def plotheatmap(u_k, k):
    plt.clf()
    plt.title(f"Temperature at t = {k*delta_t:.3f} unit time")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.pcolormesh(u_k, cmap=plt.cm.jet, vmin=0, vmax=100)
    plt.colorbar()
    return plt

# 生成动画
def animate(k):
    plotheatmap(u[k], k)

anim = animation.FuncAnimation(plt.figure(), animate, interval=1, frames=len(u), repeat=False)
anim.save("heat_equation_solution.gif")

内容的提问来源于stack exchange,提问作者Md Ahiduzzaman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 07:35:18