该代码使用热方程模拟了48小时内土壤中的温度演变,总结如下:
它导入必要的库:numpy用于数值计算,matplotlib用于绘图。
它定义了模拟中使用的常量:D(土壤的热扩散率)、深度(土壤的深度)、time_start(以秒为单位的开始时间)、time_end(以秒为单位的结束时间)和delta_t(以秒为单位的时间步长)。
它通过定义delta_x(减小的空间步长)来执行离散化,并基于给定的深度和时间参数来计算空间和时间步长的数量。
它用零初始化一个名为temperature的数组,该数组将存储不同深度和时间的温度值。
它设置温度阵列的初始条件,其中所有深度的初始温度为22.5摄氏度。
它根据给定的参数在曲面(x = 0)处设置边界条件:To(平均外部温度)和Tm(外部温度变化的幅度)。边界条件使用余弦函数随时间变化。
它对提供的真实的温度值进行插值,以匹配模拟中的时间步长。这允许在模拟温度和真实的温度之间进行比较。
它使用所提供的公式基于深度计算相移、移相。
其确定对应于4cm深度的深度指数。
它使用嵌套循环求解热方程。外部循环在时间步长上迭代,内部循环在空间步长上迭代。使用热方程公式更新每个深度和时间处的温度值。
它通过将边界条件添加到该深度的温度值来计算4 cm深度的温度(temperature_4cm)。
它使用matplotlib绘制了4cm深度处的真实的温度值和模拟温度随时间的演变。
总的来说,该代码模拟了土壤中的温度随时间的变化,并将其与提供的真实的温度值进行比较。
real_temperature_values= [22.50, 22.50, 22.30, 22.30, 22.20, 22.20, 22.10, 22.10, 22.10, 22.10, 22.10, 22.10, 22.10, 22.20, 22.30, 22.40,
22.50, 22.60, 22.70, 23.00, 23.20, 23.40, 23.70, 23.90, 24.00, 24.20, 24.40, 24.60, 24.70, 24.90, 25.10, 25.30,
25.60, 26.10, 26.60, 27.30, 28.20, 29.10, 30.00, 30.70, 31.50, 32.40, 33.20, 34.00, 34.90, 35.70, 36.50, 37.20,
37.90, 38.40, 38.90, 39.20, 39.20, 38.90, 38.50, 37.90, 37.40, 36.90, 36.40, 35.90, 35.40, 35.00, 34.50, 34.10,
33.80, 33.40, 33.10, 32.80, 32.50, 32.20, 32.00, 31.80, 31.50, 31.30, 31.00, 30.80, 30.60, 30.40, 30.10, 29.90,
29.70, 29.40, 29.20, 29.00, 28.80, 28.60, 28.40, 28.20, 28.10, 27.90, 27.70, 27.50, 27.40, 27.20, 27.10, 27.00,
26.80, 26.70, 26.60, 26.50, 26.40, 26.30, 26.20, 26.10, 26.00, 25.80, 25.80, 25.60, 25.60, 25.50, 25.40, 25.30,
25.20, 25.10, 25.00, 25.00, 24.90, 24.80, 24.70, 24.60, 24.60, 24.50, 24.50, 24.40, 24.40, 24.40, 24.30, 24.20,
24.20, 24.20, 24.20, 24.10, 24.00, 24.00, 24.00, 24.00, 23.90, 23.90, 23.80, 23.80, 23.80, 23.70, 23.60, 23.60,
23.60, 23.50, 23.50, 23.40, 23.40, 23.40, 23.40, 23.40, 23.40, 23.50, 23.50, 23.50, 23.50, 23.60, 23.60, 23.80,
23.90, 24.00, 24.20, 24.40, 24.60, 24.80, 25.00, 25.20, 25.50, 25.60, 25.80, 26.00, 26.20, 26.40, 26.60, 26.90,
27.10, 27.40, 27.90, 28.50, 29.10, 30.00, 30.60, 31.20, 31.90, 32.60, 33.40, 34.00, 34.60, 35.00, 35.20, 35.10,
35.00, 34.60, 34.30, 34.00, 34.10, 34.50, 35.10, 35.70, 36.20, 36.50, 36.90, 37.10, 37.40, 37.50, 37.50, 37.50,
37.30, 37.20, 37.10, 36.90, 36.50, 36.10, 35.70, 35.20, 34.90, 34.60, 34.40, 34.00, 33.60, 33.30, 32.90, 32.50,
32.20, 31.80, 31.50, 31.10, 30.80, 30.50, 30.10, 29.90, 29.70, 29.40, 29.20, 29.00, 28.80, 28.60, 28.40, 28.20,
28.10, 27.90, 27.70, 27.50, 27.40, 27.20, 27.00, 26.80, 26.70, 26.50, 26.40, 26.20, 26.10, 26.00, 25.80, 25.80,
25.60, 25.50, 25.40, 25.30, 25.20, 25.10, 25.00, 25.00, 24.90, 24.80, 24.70, 24.60, 24.50, 24.40, 24.40, 24.40,
24.20, 24.20, 24.20, 24.10, 24.00, 24.00, 24.00, 24.00, 23.90, 23.90, 23.80, 23.80, 23.70, 23.60, 23.60, 23.60]
import numpy as np
import matplotlib.pyplot as plt
# Constants
D = 4e-7 # Thermal diffusivity of the soil (units: m^2/s)
depth = 0.04 # Depth in m
time_start = 6 * 60 * 60 + 50 * 60 # Start time in seconds (6:50 am)
time_end = time_start + 48 * 60 * 60 # End time in seconds (next day 6:50 am)
delta_t = 60 # Time step size in seconds
# Discretization
delta_x = 0.001 # Reduced spatial step size in m
# Calculate the number of spatial and temporal steps
num_x_steps = int(depth / delta_x) + 1
num_t_steps = int((time_end - time_start) / delta_t) + 1
# Initialize temperature array
temperature = np.zeros((num_x_steps, num_t_steps))
# Set the initial conditions
temperature[:, 0] = 22.5 # Initial temperature at all depths (units: Celsius)
# Set the boundary condition at x = 0 (surface)
To = 29.364 # Average external temperature
Tm = 57.9 - 19.9 # Amplitude of external temperature variation (units: Celsius)
w = 2 * np.pi / (24 * 60 * 60) # Angular frequency of external temperature variation (units: rad/s)
boundary_condition = To + Tm * np.cos(w * np.linspace(time_start, time_end, num_t_steps))
# Real temperature values
real_temperature_values = np.interp(
np.linspace(time_start, time_end, num_t_steps),
np.linspace(time_start, time_end, len(real_temperature_values)),
real_temperature_values)
# Calculate the phase shift based on depth
dephasage = (1.38 * np.sqrt(D) * np.arange(num_x_steps)) / depth
# Calculate the depth index
depth_4cm_index = int(0.04 / delta_x) # Index corresponding to the depth of 4 cm
# Solve the heat equation
for t in range(1, num_t_steps):
temperature[0, t] = boundary_condition[t] * np.exp(-dephasage[0]) # Update the boundary condition at x = 0 (surface)
for x in range(1, num_x_steps - 1):
temperature[x, t] = temperature[x, t - 1] + (D * delta_t / (delta_x ** 2)) * (
temperature[x + 1, t - 1] - 2 * temperature[x, t - 1] + temperature[x - 1, t - 1])
# Calculate the temperature at 4 cm depth
temperature_4cm = temperature[depth_4cm_index, :] + boundary_condition
# Plot the temperature evolution
time = np.linspace(time_start, time_end, num_t_steps)
plt.plot(time, real_temperature_values, 'b-', label='Real Temperature')
plt.plot(time, temperature_4cm, 'r-', label='Simulated Temperature at 4 cm depth')
plt.xlabel('Time (s)')
plt.ylabel('Temperature (°C)')
plt.legend()
plt.title('Temperature Evolution')
plt.show()
出现错误消息“RuntimeWarning:double_scalars中遇到无效值temperature[x,t] = temperature[x,t - 1] +(D * delta_t /(delta_x**2))*(“
有谁知道如何修复错误消息?如果我把D改为10 e-20,代码可以工作,但我想使用D = 4 e-7
在讨论这些问题时,如果有人擅长物理,我会介意一些帮助,用热方程来重建真实的的温度值
1条答案
按热度按时间bqjvbblv1#
谈论物理
**1)**必须在x = 4 cm(或x > 4 cm)处定义边界条件...如果你想要0.04 m和
delta_x = 0.001
处的温度,那么你必须假设0.041 m处的温度没有变化。在0.041米处的温度保持与初始温度相同。然后用途:您需要定义:
**2)**为什么在4cm处的温度值上加上
boundary_condition
?不就是temperature_4cm = temperature[depth_4cm_index, :]
吗?谈论模拟
**1)**您使用的是显式方法,因此存在稳定性限制:
系数
D*delta_t/delta_x**2
不得大于0.5。对于
D
和delta_x
的当前值,delta_t
的限值为1.25。如果不能更改D
和delta_x
,则必须减小delta_t
。**2)**小心温度矩阵中的元素数量,因为一个巨大的矩阵可能会完全占用RAM内存并使计算机崩溃!我认为1000万是一个合理的限度。所以我建议检查
num_x_steps*num_t_steps <= 10E6
。即使有错误也要绘制图形
错误值可能用
np.NaN
或np.nan
(“不是数字”)填充。运行以下命令以验证这一点: