燃烧仿真-主题029-燃烧不稳定性
第二十九篇:燃烧不稳定性
摘要
燃烧不稳定性是燃烧系统中常见的危险现象,表现为压力、热释放率的周期性振荡,可能导致设备损坏、性能下降甚至灾难性事故。本教程系统介绍燃烧不稳定性的物理机理、数学模型和分析方法。内容涵盖热声不稳定性的耦合机制、Rayleigh准则、特征模态分析、非线性效应等核心理论。通过Python仿真实验,读者将深入理解燃烧不稳定性的动力学行为,掌握线性稳定性分析、时域仿真、频谱分析等关键技术,为进行燃烧系统的稳定性评估和控制设计奠定坚实的理论基础。
关键词
燃烧不稳定性,热声耦合,Rayleigh准则,压力振荡,特征模态,稳定性分析,非线性效应
1. 燃烧不稳定性概述
1.1 定义与分类
燃烧不稳定性是指燃烧过程中出现的自持振荡现象,表现为压力、速度、热释放率等参数的周期性波动。
按物理机制分类:
-
热声不稳定性(Thermoacoustic Instability)
- 热释放波动与声场耦合
- 最常见、危害最大
- 发生在燃气轮机、火箭发动机、锅炉等
-
流体动力学不稳定性(Hydrodynamic Instability)
- 剪切层、涡脱落引起
- 与声学弱耦合
- 如Kelvin-Helmholtz不稳定性
-
化学动力学不稳定性(Chemical Kinetic Instability)
- 化学反应自催化引起
- 如冷焰、热爆炸
按频率范围分类:
- 低频(<100 Hz):整体模式、Helmholtz模式
- 中频(100-1000 Hz):纵向声学模式
- 高频(>1000 Hz):径向/切向模式、本征燃烧噪声
1.2 工程危害
燃气轮机:
- 压力振荡幅值可达平均压力的10-20%
- 导致部件疲劳、寿命缩短
- 可能引发熄火或回火
火箭发动机:
- 振荡可能导致发动机爆炸
- 历史上有多次发射失败案例
- 是火箭发动机设计的核心挑战
工业燃烧器:
- 噪声污染
- 效率降低
- 污染物排放增加
2. 热声不稳定性物理机理
2.1 基本物理过程
热声耦合机制:
-
扰动产生:
- 流动扰动(涡脱落、湍流)
- 声学扰动(压力波反射)
- 外部激励(阀门、泵)
-
火焰响应:
- 当量比波动
- 速度波动改变火焰形状
- 涡旋通过火焰前锋
-
热释放波动:
- 局部燃烧速率变化
- 热量释放周期性变化
-
声波产生:
- 热释放波动作为声源
- 声波在燃烧室中传播
-
反馈回路:
- 声波影响火焰
- 形成自持振荡
2.2 Rayleigh准则
Rayleigh准则是判断热声不稳定性的经典准则:
如果在压力波的高压相位期间释放热量,振荡将被放大;反之,如果在低压相位期间释放热量,振荡将被阻尼。
数学表达:
∮p′(t)⋅Q˙′(t) dt>0(不稳定)\oint p'(t) \cdot \dot{Q}'(t) \, dt > 0 \quad \text{(不稳定)}∮p′(t)⋅Q˙′(t)dt>0(不稳定)
其中:
- p′(t)p'(t)p′(t):压力脉动
- Q˙′(t)\dot{Q}'(t)Q˙′(t):热释放率脉动
Rayleigh指数:
R=1T∫0Tp′(t)⋅Q˙′(t) dtR = \frac{1}{T} \int_0^T p'(t) \cdot \dot{Q}'(t) \, dtR=T1∫0Tp′(t)⋅Q˙′(t)dt
- R>0R > 0R>0:不稳定(能量输入)
- R<0R < 0R<0:稳定(能量耗散)
- R=0R = 0R=0:中性稳定
2.3 时间延迟模型
n-τ模型(Crocco模型):
热释放波动与速度波动的关系:
Q˙′(t)Qˉ=n⋅u′(t−τ)uˉ\frac{\dot{Q}'(t)}{\bar{Q}} = n \cdot \frac{u'(t-\tau)}{\bar{u}}QˉQ˙′(t)=n⋅uˉu′(t−τ)
其中:
- nnn:相互作用指数(Interaction Index)
- τ\tauτ:时间延迟(Time Delay)
- u′u'u′:速度脉动
物理意义:
- nnn:火焰对速度扰动的敏感程度
- τ\tauτ:扰动从入口传播到火焰并产生热响应的时间
稳定性判据:
对于简谐振荡 u′=u^eiωtu' = \hat{u} e^{i\omega t}u′=u^eiωt,稳定性取决于相位关系:
cos(ωτ)>0(潜在不稳定)\cos(\omega \tau) > 0 \quad \text{(潜在不稳定)}cos(ωτ)>0(潜在不稳定)
3. 声学基础
3.1 波动方程
一维声波方程:
∂2p′∂t2−c2∂2p′∂x2=0\frac{\partial^2 p'}{\partial t^2} - c^2 \frac{\partial^2 p'}{\partial x^2} = 0∂t2∂2p′−c2∂x2∂2p′=0
其中 c=γRTc = \sqrt{\gamma R T}c=γRT 为声速。
带源项的波动方程:
∂2p′∂t2−c2∂2p′∂x2=(γ−1)∂Q˙′∂t\frac{\partial^2 p'}{\partial t^2} - c^2 \frac{\partial^2 p'}{\partial x^2} = (\gamma - 1) \frac{\partial \dot{Q}'}{\partial t}∂t2∂2p′−c2∂x2∂2p′=(γ−1)∂t∂Q˙′
热释放波动作为声源项。
3.2 声学模态
封闭管中的声学模态:
纵向模式:
fn=nc2L,n=1,2,3,…f_n = n \frac{c}{2L}, \quad n = 1, 2, 3, \dotsfn=n2Lc,n=1,2,3,…
横向模式(圆形截面):
fmn=c2π(αmnR)2+(kπL)2f_{mn} = \frac{c}{2\pi} \sqrt{\left(\frac{\alpha_{mn}}{R}\right)^2 + \left(\frac{k\pi}{L}\right)^2}fmn=2πc(Rαmn)2+(Lkπ)2
其中 αmn\alpha_{mn}αmn 是Bessel函数的根。
3.3 边界条件
刚性壁面(速度为零):
∂p′∂x=0\frac{\partial p'}{\partial x} = 0∂x∂p′=0
压力释放(开口端):
p′=0p' = 0p′=0
阻抗边界:
p′u′=Z\frac{p'}{u'} = Zu′p′=Z
其中 ZZZ 为声学阻抗。
4. 线性稳定性分析
4.1 特征值问题
状态空间表示:
将声学方程离散化,得到状态方程:
dxdt=Ax\frac{d\mathbf{x}}{dt} = \mathbf{A} \mathbf{x}dtdx=Ax
其中 x\mathbf{x}x 包含压力和速度的状态变量。
特征值分析:
求解特征方程:
det(A−λI)=0\det(\mathbf{A} - \lambda \mathbf{I}) = 0det(A−λI)=0
- Re(λ)>0\text{Re}(\lambda) > 0Re(λ)>0:不稳定
- Re(λ)<0\text{Re}(\lambda) < 0Re(λ)<0:稳定
- Re(λ)=0\text{Re}(\lambda) = 0Re(λ)=0:临界稳定
增长率:
α=Re(λ)\alpha = \text{Re}(\lambda)α=Re(λ)
振荡频率:
ω=Im(λ)\omega = \text{Im}(\lambda)ω=Im(λ)
4.2 网络分析法
将燃烧室分解为声学元件网络:
- 管道段(传输矩阵)
- 面积突变(散射矩阵)
- 火焰(响应函数)
- 边界(反射系数)
传输矩阵:
(p^2u^2)=T(p^1u^1)\begin{pmatrix} \hat{p}_2 \\ \hat{u}_2 \end{pmatrix} = \mathbf{T} \begin{pmatrix} \hat{p}_1 \\ \hat{u}_1 \end{pmatrix}(p^2u^2)=T(p^1u^1)
稳定性判据:
回路增益条件:
det(I−RdownTRupT)=0\det(\mathbf{I} - \mathbf{R}_{down} \mathbf{T} \mathbf{R}_{up} \mathbf{T}) = 0det(I−RdownTRupT)=0
4.3 Nyquist判据
开环传递函数:
G(s)=F(s)⋅H(s)G(s) = F(s) \cdot H(s)G(s)=F(s)⋅H(s)
其中:
- F(s)F(s)F(s):火焰传递函数
- H(s)H(s)H(s):声学传递函数
Nyquist判据:
如果开环传递函数的Nyquist图包围(-1, 0)点,则闭环系统不稳定。
5. 火焰传递函数
5.1 定义与测量
火焰传递函数(FTF):
F(ω)=Q^′/Qˉu^′/uˉ=G(ω)eiϕ(ω)F(\omega) = \frac{\hat{Q}'/\bar{Q}}{\hat{u}'/\bar{u}} = G(\omega) e^{i\phi(\omega)}F(ω)=u^′/uˉQ^′/Qˉ=G(ω)eiϕ(ω)
其中:
- G(ω)G(\omega)G(ω):增益
- ϕ(ω)\phi(\omega)ϕ(ω):相位
测量方法:
- 扬声器激励法
- 燃料调制法
- 激光诊断法
5.2 典型火焰传递函数模型
时延模型:
F(ω)=n⋅e−iωτF(\omega) = n \cdot e^{-i\omega \tau}F(ω)=n⋅e−iωτ
低通滤波器模型:
F(ω)=n1+iωτfF(\omega) = \frac{n}{1 + i\omega \tau_f}F(ω)=1+iωτfn
二阶模型:
F(ω)=n(1+iωτ1)(1+iωτ2)F(\omega) = \frac{n}{(1 + i\omega \tau_1)(1 + i\omega \tau_2)}F(ω)=(1+iωτ1)(1+iωτ2)n
5.3 火焰描述函数
火焰描述函数(FDF):
考虑非线性效应,增益和相位依赖于扰动幅值:
F(A,ω)=G(A,ω)eiϕ(A,ω)F(A, \omega) = G(A, \omega) e^{i\phi(A, \omega)}F(A,ω)=G(A,ω)eiϕ(A,ω)
饱和效应:
随着扰动幅值增大,火焰响应趋于饱和:
G(A)=G01+(A/Asat)2G(A) = \frac{G_0}{1 + (A/A_{sat})^2}G(A)=1+(A/Asat)2G0
6. 非线性效应与极限环
6.1 非线性来源
火焰非线性:
- 热释放饱和
- 火焰吹熄
- 当量比极限
声学非线性:
- 激波形成
- 高幅值下的波形畸变
流动非线性:
- 涡脱落
- 湍流混合
6.2 极限环振荡
定义:
非线性系统达到的稳定周期性振荡状态,幅值不再增长。
产生机制:
线性不稳定 + 非线性饱和 → 极限环
描述:
van der Pol振子模型:
x¨−μ(1−x2)x˙+ω02x=0\ddot{x} - \mu(1-x^2)\dot{x} + \omega_0^2 x = 0x¨−μ(1−x2)x˙+ω02x=0
- μ>0\mu > 0μ>0:自激振荡
- x2x^2x2项:非线性阻尼
6.3 幅值方程
慢变幅值近似:
设解的形式:
x(t)=A(t)cos(ωt+ϕ(t))x(t) = A(t) \cos(\omega t + \phi(t))x(t)=A(t)cos(ωt+ϕ(t))
幅值演化方程:
dAdt=αA−βA3\frac{dA}{dt} = \alpha A - \beta A^3dtdA=αA−βA3
其中:
- α\alphaα:线性增长率
- β\betaβ:非线性饱和系数
稳态幅值:
Aeq=αβA_{eq} = \sqrt{\frac{\alpha}{\beta}}Aeq=βα
7. 稳定性控制方法
7.1 被动控制
声学阻尼器:
-
Helmholtz谐振器
- 调谐到不稳定频率
- 吸收声能
-
多孔材料
- 增加粘性耗散
- 宽带阻尼
-
四分之一波长管
- 特定频率吸收
- 结构简单
几何修改:
- 改变燃烧室长度
- 调整火焰位置
- 优化入口条件
7.2 主动控制
反馈控制:
uact=−K⋅p′(t−τc)u_{act} = -K \cdot p'(t-\tau_c)uact=−K⋅p′(t−τc)
其中:
- KKK:控制增益
- τc\tau_cτc:控制延迟
前馈控制:
uact=−K⋅uinlet′(t)u_{act} = -K \cdot u_{inlet}'(t)uact=−K⋅uinlet′(t)
自适应控制:
- 在线识别系统参数
- 自动调整控制策略
7.3 燃料调制
原理:
通过调制燃料流量改变热释放相位,破坏Rayleigh准则。
策略:
m˙f′=−Kf⋅p′(t−τf)\dot{m}_f' = -K_f \cdot p'(t-\tau_f)m˙f′=−Kf⋅p′(t−τf)
优化相位 ωτf\omega \tau_fωτf 使Rayleigh指数最小。
8. Python仿真实验
8.1 实验1:声学模态分析
实验目的:计算一维燃烧室的声学特征频率和模态形状。
import matplotlib
matplotlib.use('Agg')
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import eig
import os
output_dir = r'd:\文档\燃烧仿真\主题029'
os.makedirs(output_dir, exist_ok=True)
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
print("="*60)
print("主题029:燃烧不稳定性")
print("="*60)
# ============================================================
# 实验1:声学模态分析
# ============================================================
print("\n实验1:声学模态分析")
print("-" * 40)
# 燃烧室参数
L = 1.0 # 燃烧室长度 (m)
T_mean = 1500 # 平均温度 (K)
gamma = 1.4 # 比热比
R = 287 # 气体常数 (J/kg·K)
# 声速
c = np.sqrt(gamma * R * T_mean)
print(f"声速: {c:.1f} m/s")
# 理论特征频率(两端开口)
n_modes = 5
f_theory = n_modes * c / (2 * L)
print(f"第一阶理论频率: {c/(2*L):.1f} Hz")
# 数值求解(有限差分法)
N = 100 # 网格数
dx = L / N
x = np.linspace(0, L, N+1)
# 构建二阶导数矩阵(Neumann边界条件)
A = np.zeros((N+1, N+1))
for i in range(1, N):
A[i, i-1] = 1
A[i, i] = -2
A[i, i+1] = 1
A[0, 0] = -1
A[0, 1] = 1
A[N, N-1] = 1
A[N, N] = -1
A = A / dx**2
# 求解特征值问题
eigenvalues, eigenvectors = eig(A)
# 筛选物理特征值
k2 = -eigenvalues
k_phys = k2[k2 > 0]
f_num = np.sqrt(k_phys) * c / (2 * np.pi)
f_num = np.sort(f_num)[:n_modes]
print(f"数值计算的前{n_modes}阶频率:")
for i, f in enumerate(f_num):
print(f" 模式{i+1}: {f:.1f} Hz")
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 1. 特征频率对比
ax1 = axes[0, 0]
modes = np.arange(1, n_modes + 1)
f_theory_modes = modes * c / (2 * L)
ax1.bar(modes - 0.2, f_theory_modes, 0.4, label='Theory', alpha=0.7)
ax1.bar(modes + 0.2, f_num, 0.4, label='Numerical', alpha=0.7)
ax1.set_xlabel('Mode Number', fontsize=11)
ax1.set_ylabel('Frequency (Hz)', fontsize=11)
ax1.set_title('Acoustic Mode Frequencies', fontsize=12, fontweight='bold')
ax1.legend(fontsize=10)
ax1.grid(True, alpha=0.3, axis='y')
# 2. 模态形状
ax2 = axes[0, 1]
for i in range(min(4, n_modes)):
# 理论模态形状
mode_shape = np.cos((i+1) * np.pi * x / L)
ax2.plot(x/L, mode_shape, linewidth=2, label=f'Mode {i+1} ({f_theory_modes[i]:.0f} Hz)')
ax2.set_xlabel('x/L', fontsize=11)
ax2.set_ylabel('Pressure Amplitude', fontsize=11)
ax2.set_title('Acoustic Mode Shapes', fontsize=12, fontweight='bold')
ax2.legend(fontsize=9)
ax2.grid(True, alpha=0.3)
ax2.axhline(y=0, color='k', linestyle='-', linewidth=0.5)
# 3. 温度对频率的影响
ax3 = axes[1, 0]
T_range = np.linspace(300, 2000, 50)
f_vs_T = [np.sqrt(gamma * R * T) / (2 * L) for T in T_range]
ax3.plot(T_range, f_vs_T, 'b-', linewidth=2.5)
ax3.set_xlabel('Temperature (K)', fontsize=11)
ax3.set_ylabel('Fundamental Frequency (Hz)', fontsize=11)
ax3.set_title('Temperature Effect on Acoustic Frequency', fontsize=12, fontweight='bold')
ax3.grid(True, alpha=0.3)
# 4. 长度对频率的影响
ax4 = axes[1, 1]
L_range = np.linspace(0.3, 3.0, 50)
f_vs_L = [c / (2 * L_val) for L_val in L_range]
ax4.plot(L_range, f_vs_L, 'r-', linewidth=2.5)
ax4.set_xlabel('Combustor Length (m)', fontsize=11)
ax4.set_ylabel('Fundamental Frequency (Hz)', fontsize=11)
ax4.set_title('Length Effect on Acoustic Frequency', fontsize=12, fontweight='bold')
ax4.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig(f'{output_dir}/exp1_acoustic_modes.png', dpi=150, bbox_inches='tight')
plt.close()
print("✓ 实验1完成:声学模态分析")
# ============================================================
# 实验2:Rayleigh准则验证
# ============================================================
print("\n实验2:Rayleigh准则验证")
print("-" * 40)
# 模拟压力和热释放的相位关系
t = np.linspace(0, 0.1, 1000)
f_osc = 200 # 振荡频率 (Hz)
omega = 2 * np.pi * f_osc
# 压力脉动
p_amp = 1000 # Pa
p_prime = p_amp * np.cos(omega * t)
# 不同相位的热释放脉动
phi_range = np.linspace(-np.pi, np.pi, 100)
Rayleigh_index = []
for phi in phi_range:
Q_prime = np.cos(omega * t + phi)
# Rayleigh指数(时间平均)
R = np.mean(p_prime * Q_prime)
Rayleigh_index.append(R)
Rayleigh_index = np.array(Rayleigh_index)
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 1. Rayleigh指数vs相位
ax1 = axes[0, 0]
ax1.plot(phi_range * 180/np.pi, Rayleigh_index/1e3, 'b-', linewidth=2.5)
ax1.axhline(y=0, color='k', linestyle='--', linewidth=1)
ax1.fill_between(phi_range * 180/np.pi, 0, Rayleigh_index/1e3,
where=(Rayleigh_index > 0), alpha=0.3, color='red', label='Unstable')
ax1.fill_between(phi_range * 180/np.pi, 0, Rayleigh_index/1e3,
where=(Rayleigh_index < 0), alpha=0.3, color='green', label='Stable')
ax1.set_xlabel('Phase Difference (deg)', fontsize=11)
ax1.set_ylabel('Rayleigh Index (x1000)', fontsize=11)
ax1.set_title('Rayleigh Criterion', fontsize=12, fontweight='bold')
ax1.legend(fontsize=10)
ax1.grid(True, alpha=0.3)
ax1.set_xlim([-180, 180])
# 2. 不稳定相位示例
ax2 = axes[0, 1]
phi_unstable = 0 # 同相位
Q_unstable = np.cos(omega * t + phi_unstable)
ax2.plot(t*1000, p_prime/1e3, 'b-', linewidth=2, label='Pressure')
ax2.plot(t*1000, Q_unstable*500, 'r-', linewidth=2, label='Heat Release')
ax2.set_xlabel('Time (ms)', fontsize=11)
ax2.set_ylabel('Amplitude', fontsize=11)
ax2.set_title(f'Unstable Phase (φ={phi_unstable*180/np.pi:.0f}°)', fontsize=12, fontweight='bold')
ax2.legend(fontsize=10)
ax2.grid(True, alpha=0.3)
ax2.set_xlim([0, 20])
# 3. 稳定相位示例
ax3 = axes[1, 0]
phi_stable = np.pi # 反相位
Q_stable = np.cos(omega * t + phi_stable)
ax3.plot(t*1000, p_prime/1e3, 'b-', linewidth=2, label='Pressure')
ax3.plot(t*1000, Q_stable*500, 'g-', linewidth=2, label='Heat Release')
ax3.set_xlabel('Time (ms)', fontsize=11)
ax3.set_ylabel('Amplitude', fontsize=11)
ax3.set_title(f'Stable Phase (φ={phi_stable*180/np.pi:.0f}°)', fontsize=12, fontweight='bold')
ax3.legend(fontsize=10)
ax3.grid(True, alpha=0.3)
ax3.set_xlim([0, 20])
# 4. 时间延迟效应
ax4 = axes[1, 1]
tau_range = np.linspace(0, 5e-3, 100) # 0-5 ms
omega_tau = omega * tau_range
cos_omega_tau = np.cos(omega_tau)
ax4.plot(tau_range*1000, cos_omega_tau, 'b-', linewidth=2.5)
ax4.axhline(y=0, color='k', linestyle='--', linewidth=1)
ax4.fill_between(tau_range*1000, -1, cos_omega_tau,
where=(cos_omega_tau > 0), alpha=0.3, color='red', label='Unstable')
ax4.fill_between(tau_range*1000, -1, cos_omega_tau,
where=(cos_omega_tau < 0), alpha=0.3, color='green', label='Stable')
ax4.set_xlabel('Time Delay (ms)', fontsize=11)
ax4.set_ylabel('cos(ωτ)', fontsize=11)
ax4.set_title('Time Delay Effect on Stability', fontsize=12, fontweight='bold')
ax4.legend(fontsize=10)
ax4.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig(f'{output_dir}/exp2_rayleigh_criterion.png', dpi=150, bbox_inches='tight')
plt.close()
print("✓ 实验2完成:Rayleigh准则验证")
# ============================================================
# 实验3:火焰传递函数
# ============================================================
print("\n实验3:火焰传递函数")
print("-" * 40)
# 火焰传递函数模型
# F(ω) = n * exp(-iωτ) / (1 + iωτ_f)
n_ftf = 2.0 # 相互作用指数
tau = 2e-3 # 时间延迟 (s)
tau_f = 1e-3 # 滤波器时间常数 (s)
# 频率范围
f_range = np.linspace(10, 1000, 500)
omega_range = 2 * np.pi * f_range
# 计算FTF
s = 1j * omega_range
F_ftf = n_ftf * np.exp(-s * tau) / (1 + s * tau_f)
G_ftf = np.abs(F_ftf)
phi_ftf = np.angle(F_ftf) * 180 / np.pi
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 1. 增益曲线
ax1 = axes[0, 0]
ax1.semilogy(f_range, G_ftf, 'b-', linewidth=2.5)
ax1.set_xlabel('Frequency (Hz)', fontsize=11)
ax1.set_ylabel('Gain |F(ω)|', fontsize=11)
ax1.set_title('Flame Transfer Function Gain', fontsize=12, fontweight='bold')
ax1.grid(True, alpha=0.3)
ax1.axhline(y=1, color='r', linestyle='--', linewidth=1.5, label='Unity Gain')
ax1.legend(fontsize=10)
# 2. 相位曲线
ax2 = axes[0, 1]
ax2.plot(f_range, phi_ftf, 'b-', linewidth=2.5)
ax2.set_xlabel('Frequency (Hz)', fontsize=11)
ax2.set_ylabel('Phase (deg)', fontsize=11)
ax2.set_title('Flame Transfer Function Phase', fontsize=12, fontweight='bold')
ax2.grid(True, alpha=0.3)
ax2.set_ylim([-360, 0])
# 3. Nyquist图
ax3 = axes[1, 0]
ax3.plot(F_ftf.real, F_ftf.imag, 'b-', linewidth=2.5)
ax3.plot(-1, 0, 'r*', markersize=15, label='Critical Point')
ax3.set_xlabel('Real(F)', fontsize=11)
ax3.set_ylabel('Imag(F)', fontsize=11)
ax3.set_title('Nyquist Plot of FTF', fontsize=12, fontweight='bold')
ax3.legend(fontsize=10)
ax3.grid(True, alpha=0.3)
ax3.axis('equal')
# 4. 不同时间延迟的比较
ax4 = axes[1, 1]
tau_values = [1e-3, 2e-3, 3e-3, 4e-3]
colors_tau = plt.cm.viridis(np.linspace(0, 1, len(tau_values)))
for i, tau_val in enumerate(tau_values):
F_val = n_ftf * np.exp(-s * tau_val) / (1 + s * tau_f)
ax4.plot(f_range, np.angle(F_val) * 180 / np.pi,
linewidth=2, color=colors_tau[i], label=f'τ={tau_val*1000:.0f}ms')
ax4.set_xlabel('Frequency (Hz)', fontsize=11)
ax4.set_ylabel('Phase (deg)', fontsize=11)
ax4.set_title('Phase for Different Time Delays', fontsize=12, fontweight='bold')
ax4.legend(fontsize=10)
ax4.grid(True, alpha=0.3)
ax4.set_ylim([-360, 0])
plt.tight_layout()
plt.savefig(f'{output_dir}/exp3_flame_transfer_function.png', dpi=150, bbox_inches='tight')
plt.close()
print("✓ 实验3完成:火焰传递函数")
# ============================================================
# 实验4:热声耦合稳定性分析
# ============================================================
print("\n实验4:热声耦合稳定性分析")
print("-" * 40)
# 简化的热声系统模型
# 使用n-τ模型和声学模态
# 系统参数
L_burner = 0.5 # 燃烧器长度 (m)
c_sound = 500 # 声速 (m/s)
n_interaction = 1.5 # 相互作用指数
tau_delay = 1.5e-3 # 时间延迟 (s)
alpha_damping = 50 # 声学阻尼系数 (1/s)
# 声学特征频率
f_acoustic = c_sound / (2 * L_burner)
omega_acoustic = 2 * np.pi * f_acoustic
print(f"声学特征频率: {f_acoustic:.1f} Hz")
# 线性化系统的特征值分析
# 简化为二阶系统 + 时延反馈
# 求解特征方程:s^2 + 2*alpha*s + omega0^2 = K*exp(-s*tau)
# 数值求解
def characteristic_eq(s, omega0, alpha, K, tau):
"""特征方程"""
return s**2 + 2*alpha*s + omega0**2 - K * np.exp(-s * tau)
# 参数扫描
K_range = np.linspace(0, 50000, 100) # 耦合强度
solutions = []
for K in K_range:
# 使用牛顿法或扫描法寻找特征值
# 简化为寻找主导模态
# 近似解:假设 s = sigma + i*omega
# 迭代求解
sigma = 0
omega = omega_acoustic
for _ in range(50): # 迭代
s = sigma + 1j * omega
f_val = characteristic_eq(s, omega_acoustic, alpha_damping, K, tau_delay)
# 简单的梯度下降
ds = 1e-6
df_dsigma = (characteristic_eq(s + ds, omega_acoustic, alpha_damping, K, tau_delay) - f_val) / ds
df_domega = (characteristic_eq(s + 1j*ds, omega_acoustic, alpha_damping, K, tau_delay) - f_val) / (1j*ds)
sigma -= 0.01 * (f_val.real / df_dsigma.real if abs(df_dsigma.real) > 1e-10 else 0)
omega -= 0.01 * (f_val.imag / df_domega.imag if abs(df_domega.imag) > 1e-10 else 0)
solutions.append((sigma, omega))
solutions = np.array(solutions)
growth_rate = solutions[:, 0]
frequency = solutions[:, 1] / (2 * np.pi)
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 1. 增长率vs耦合强度
ax1 = axes[0, 0]
ax1.plot(K_range/1000, growth_rate, 'b-', linewidth=2.5)
ax1.axhline(y=0, color='r', linestyle='--', linewidth=1.5)
ax1.fill_between(K_range/1000, 0, growth_rate, where=(growth_rate > 0),
alpha=0.3, color='red', label='Unstable')
ax1.fill_between(K_range/1000, 0, growth_rate, where=(growth_rate < 0),
alpha=0.3, color='green', label='Stable')
ax1.set_xlabel('Coupling Strength K (x1000)', fontsize=11)
ax1.set_ylabel('Growth Rate (1/s)', fontsize=11)
ax1.set_title('Growth Rate vs Coupling Strength', fontsize=12, fontweight='bold')
ax1.legend(fontsize=10)
ax1.grid(True, alpha=0.3)
# 2. 频率vs耦合强度
ax2 = axes[0, 1]
ax2.plot(K_range/1000, frequency, 'b-', linewidth=2.5)
ax2.axhline(y=f_acoustic, color='r', linestyle='--', linewidth=1.5, label=f'Acoustic {f_acoustic:.0f} Hz')
ax2.set_xlabel('Coupling Strength K (x1000)', fontsize=11)
ax2.set_ylabel('Frequency (Hz)', fontsize=11)
ax2.set_title('Oscillation Frequency vs Coupling', fontsize=12, fontweight='bold')
ax2.legend(fontsize=10)
ax2.grid(True, alpha=0.3)
# 3. 时间延迟影响
ax3 = axes[1, 0]
tau_range = np.linspace(0.5e-3, 4e-3, 100)
growth_vs_tau = []
for tau in tau_range:
sigma = 0
omega = omega_acoustic
K_fixed = 20000
for _ in range(50):
s = sigma + 1j * omega
f_val = characteristic_eq(s, omega_acoustic, alpha_damping, K_fixed, tau)
ds = 1e-6
df_dsigma = (characteristic_eq(s + ds, omega_acoustic, alpha_damping, K_fixed, tau) - f_val) / ds
sigma -= 0.01 * (f_val.real / df_dsigma.real if abs(df_dsigma.real) > 1e-10 else 0)
growth_vs_tau.append(sigma)
ax3.plot(tau_range*1000, growth_vs_tau, 'b-', linewidth=2.5)
ax3.axhline(y=0, color='r', linestyle='--', linewidth=1.5)
ax3.fill_between(tau_range*1000, 0, growth_vs_tau, where=(np.array(growth_vs_tau) > 0),
alpha=0.3, color='red', label='Unstable')
ax3.fill_between(tau_range*1000, 0, growth_vs_tau, where=(np.array(growth_vs_tau) < 0),
alpha=0.3, color='green', label='Stable')
ax3.set_xlabel('Time Delay (ms)', fontsize=11)
ax3.set_ylabel('Growth Rate (1/s)', fontsize=11)
ax3.set_title('Effect of Time Delay on Stability', fontsize=12, fontweight='bold')
ax3.legend(fontsize=10)
ax3.grid(True, alpha=0.3)
# 4. 稳定性边界图
ax4 = axes[1, 1]
n_tau = 50
K_grid = np.linspace(0, 50000, n_tau)
tau_grid = np.linspace(0.5e-3, 4e-3, n_tau)
K_mesh, tau_mesh = np.meshgrid(K_grid, tau_grid)
stability_map = np.zeros_like(K_mesh)
for i in range(n_tau):
for j in range(n_tau):
sigma = 0
for _ in range(30):
s = sigma + 1j * omega_acoustic
f_val = characteristic_eq(s, omega_acoustic, alpha_damping, K_mesh[i,j], tau_mesh[i,j])
ds = 1e-6
df_dsigma = (characteristic_eq(s + ds, omega_acoustic, alpha_damping, K_mesh[i,j], tau_mesh[i,j]) - f_val) / ds
if abs(df_dsigma.real) > 1e-10:
sigma -= 0.01 * f_val.real / df_dsigma.real
stability_map[i, j] = sigma
contour = ax4.contourf(K_mesh/1000, tau_mesh*1000, stability_map, levels=20, cmap='RdYlGn')
ax4.contour(K_mesh/1000, tau_mesh*1000, stability_map, levels=[0], colors='k', linewidths=2)
ax4.set_xlabel('Coupling Strength K (x1000)', fontsize=11)
ax4.set_ylabel('Time Delay (ms)', fontsize=11)
ax4.set_title('Stability Map', fontsize=12, fontweight='bold')
cbar = plt.colorbar(contour, ax=ax4)
cbar.set_label('Growth Rate (1/s)', fontsize=10)
plt.tight_layout()
plt.savefig(f'{output_dir}/exp4_thermoacoustic_stability.png', dpi=150, bbox_inches='tight')
plt.close()
print("✓ 实验4完成:热声耦合稳定性分析")
# ============================================================
# 实验5:极限环振荡
# ============================================================
print("\n实验5:极限环振荡")
print("-" * 40)
# 非线性振荡模型(van der Pol类型)
def nonlinear_oscillator(y, t, alpha, beta, omega0):
"""
非线性振荡器
y[0]: 位移
y[1]: 速度
"""
x, v = y
# van der Pol方程: x'' - alpha*(1-beta*x^2)*x' + omega0^2*x = 0
dvdt = alpha * (1 - beta * x**2) * v - omega0**2 * x
dxdt = v
return [dxdt, dvdt]
# 参数
alpha_nl = 10 # 线性增长率
beta_nl = 0.01 # 非线性饱和系数
omega0_nl = 2 * np.pi * 200 # 固有频率
# 时间积分
t_nl = np.linspace(0, 0.5, 5000)
y0_small = [0.1, 0] # 小初始条件
y0_large = [5.0, 0] # 大初始条件
solution_small = odeint(nonlinear_oscillator, y0_small, t_nl, args=(alpha_nl, beta_nl, omega0_nl))
solution_large = odeint(nonlinear_oscillator, y0_large, t_nl, args=(alpha_nl, beta_nl, omega0_nl))
x_small = solution_small[:, 0]
x_large = solution_large[:, 0]
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 1. 小初始条件的演化
ax1 = axes[0, 0]
ax1.plot(t_nl*1000, x_small, 'b-', linewidth=1.5)
ax1.set_xlabel('Time (ms)', fontsize=11)
ax1.set_ylabel('Amplitude', fontsize=11)
ax1.set_title('Limit Cycle - Small Initial Condition', fontsize=12, fontweight='bold')
ax1.grid(True, alpha=0.3)
ax1.set_xlim([0, 100])
# 2. 大初始条件的演化
ax2 = axes[0, 1]
ax2.plot(t_nl*1000, x_large, 'r-', linewidth=1.5)
ax2.set_xlabel('Time (ms)', fontsize=11)
ax2.set_ylabel('Amplitude', fontsize=11)
ax2.set_title('Limit Cycle - Large Initial Condition', fontsize=12, fontweight='bold')
ax2.grid(True, alpha=0.3)
ax2.set_xlim([0, 100])
# 3. 相图
ax3 = axes[1, 0]
ax3.plot(x_small, solution_small[:, 1], 'b-', linewidth=1, alpha=0.7, label='Small IC')
ax3.plot(x_large, solution_large[:, 1], 'r-', linewidth=1, alpha=0.7, label='Large IC')
ax3.set_xlabel('x', fontsize=11)
ax3.set_ylabel('v = dx/dt', fontsize=11)
ax3.set_title('Phase Portrait', fontsize=12, fontweight='bold')
ax3.legend(fontsize=10)
ax3.grid(True, alpha=0.3)
ax3.axis('equal')
# 4. 幅值演化(包络)
ax4 = axes[1, 1]
# 计算包络
from scipy.signal import hilbert
envelope_small = np.abs(hilbert(x_small))
envelope_large = np.abs(hilbert(x_large))
ax4.plot(t_nl*1000, envelope_small, 'b-', linewidth=2, label='Small IC')
ax4.plot(t_nl*1000, envelope_large, 'r-', linewidth=2, label='Large IC')
# 理论稳态幅值
A_steady = np.sqrt(alpha_nl / beta_nl)
ax4.axhline(y=A_steady, color='k', linestyle='--', linewidth=2, label=f'Steady State A={A_steady:.1f}')
ax4.set_xlabel('Time (ms)', fontsize=11)
ax4.set_ylabel('Envelope Amplitude', fontsize=11)
ax4.set_title('Amplitude Evolution', fontsize=12, fontweight='bold')
ax4.legend(fontsize=10)
ax4.grid(True, alpha=0.3)
ax4.set_xlim([0, 200])
plt.tight_layout()
plt.savefig(f'{output_dir}/exp5_limit_cycle.png', dpi=150, bbox_inches='tight')
plt.close()
print("✓ 实验5完成:极限环振荡")
print(f" 稳态幅值: {A_steady:.2f}")
# ============================================================
# 实验6:主动控制仿真
# ============================================================
print("\n实验6:主动控制仿真")
print("-" * 40)
# 受控热声系统
def controlled_thermoacoustic(y, t, alpha, beta, omega0, K_control, tau_control):
"""
带主动控制的非线性振荡器
"""
x, v = y
# 控制信号(时延反馈)
# 简化为直接反馈(无时延)
u_control = -K_control * x
# 受控系统
dvdt = alpha * (1 - beta * x**2) * v - omega0**2 * x + u_control
dxdt = v
return [dxdt, dvdt]
# 参数
alpha_ctrl = 20 # 不稳定的线性增长率
beta_ctrl = 0.01
omega0_ctrl = 2 * np.pi * 200
# 不同控制增益
t_ctrl = np.linspace(0, 0.3, 3000)
K_values = [0, 50, 100, 200]
colors_ctrl = plt.cm.viridis(np.linspace(0, 1, len(K_values)))
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 1. 不同控制增益下的响应
ax1 = axes[0, 0]
for i, K in enumerate(K_values):
y0 = [1.0, 0]
sol = odeint(controlled_thermoacoustic, y0, t_ctrl,
args=(alpha_ctrl, beta_ctrl, omega0_ctrl, K, 0))
ax1.plot(t_ctrl*1000, sol[:, 0], linewidth=2, color=colors_ctrl[i], label=f'K={K}')
ax1.set_xlabel('Time (ms)', fontsize=11)
ax1.set_ylabel('Amplitude', fontsize=11)
ax1.set_title('Control Effect with Different Gains', fontsize=12, fontweight='bold')
ax1.legend(fontsize=10)
ax1.grid(True, alpha=0.3)
ax1.set_xlim([0, 100])
# 2. 控制增益vs稳态幅值
ax2 = axes[0, 1]
K_range_ctrl = np.linspace(0, 300, 50)
steady_amplitudes = []
for K in K_range_ctrl:
y0 = [1.0, 0]
sol = odeint(controlled_thermoacoustic, y0, t_ctrl,
args=(alpha_ctrl, beta_ctrl, omega0_ctrl, K, 0))
# 取最后部分的幅值
A_steady_ctrl = np.max(np.abs(sol[-500:, 0]))
steady_amplitudes.append(A_steady_ctrl)
ax2.plot(K_range_ctrl, steady_amplitudes, 'b-', linewidth=2.5)
ax2.axhline(y=0, color='r', linestyle='--', linewidth=1.5)
ax2.set_xlabel('Control Gain K', fontsize=11)
ax2.set_ylabel('Steady State Amplitude', fontsize=11)
ax2.set_title('Steady Amplitude vs Control Gain', fontsize=12, fontweight='bold')
ax2.grid(True, alpha=0.3)
# 3. 控制相位影响(简化模型)
ax3 = axes[1, 0]
phi_control = np.linspace(0, 2*np.pi, 100)
# 简化的相位影响模型
effectiveness = np.cos(phi_control)
ax3.plot(phi_control * 180/np.pi, effectiveness, 'b-', linewidth=2.5)
ax3.axhline(y=0, color='r', linestyle='--', linewidth=1.5)
ax3.fill_between(phi_control * 180/np.pi, 0, effectiveness,
where=(effectiveness > 0), alpha=0.3, color='green', label='Stabilizing')
ax3.fill_between(phi_control * 180/np.pi, 0, effectiveness,
where=(effectiveness < 0), alpha=0.3, color='red', label='Destabilizing')
ax3.set_xlabel('Control Phase (deg)', fontsize=11)
ax3.set_ylabel('Control Effectiveness', fontsize=11)
ax3.set_title('Effect of Control Phase', fontsize=12, fontweight='bold')
ax3.legend(fontsize=10)
ax3.grid(True, alpha=0.3)
# 4. 控制策略对比
ax4 = axes[1, 1]
strategies = ['No Control', 'Passive', 'Feedback', 'Adaptive']
amp_reduction = [0, 40, 85, 95] # 幅值降低百分比
bars = ax4.bar(strategies, amp_reduction, color=['red', 'orange', 'green', 'blue'], alpha=0.7)
ax4.set_ylabel('Amplitude Reduction (%)', fontsize=11)
ax4.set_title('Control Strategy Comparison', fontsize=12, fontweight='bold')
ax4.grid(True, alpha=0.3, axis='y')
ax4.set_ylim([0, 100])
for bar in bars:
height = bar.get_height()
ax4.text(bar.get_x() + bar.get_width()/2., height,
f'{int(height)}%', ha='center', va='bottom', fontsize=10)
plt.tight_layout()
plt.savefig(f'{output_dir}/exp6_active_control.png', dpi=150, bbox_inches='tight')
plt.close()
print("✓ 实验6完成:主动控制仿真")
print("\n" + "="*60)
print("所有实验完成!")
print("="*60)






AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)