You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于菲涅耳方程计算波长相关复折射率薄膜反射谱与预期结果不符的问题排查

基于菲涅耳方程计算波长相关复折射率薄膜反射谱与预期结果不符的问题排查

我帮你排查一下代码里的几个关键问题,这些问题直接导致了你的结果和预期不符:


1. 复折射率定义完全错误

这是最核心的问题!你在代码里写了:

N2 = Thin_film[Thin_film.columns[1]] + Thin_film[Thin_film.columns[1]]*1j

复折射率的正确形式是实部(折射率n) + 虚部(消光系数k)×j,而你把同一列数据既当作实部又当作虚部,相当于让消光系数k和折射率n完全相等,这和真实的硅材料光学参数完全不符,直接导致后续所有计算偏离正确值。

假设你的数据文件中,第一列是波长,第二列是实部n,第三列是虚部k,正确的定义应该是:

N2 = Thin_film.iloc[:, 1].values + 1j * Thin_film.iloc[:, 2].values

2. 相位差δ的计算错误

你当前的delta计算使用了复折射率的模的平方,这完全不符合理论公式:

delta = 2 * np.pi * (1/lamb[i]) * d * np.sqrt(abs(N2[i])**2 - (np.sin(ang_1)**2))

正确的δ应该基于复折射率本身计算(垂直入射时θ₁=0,sinθ₁=0,cosθ₂=1,公式可以简化):

# 垂直入射时,δ = (4π/λ) * d * N2 (往返的相位变化)
delta = (4 * np.pi * d / lamb[i]) * N2[i]

这里的N2是复折射率,所以δ是复数,既包含相位变化也包含吸收衰减,这才符合有吸收薄膜的反射计算逻辑。


3. 不必要的归一化处理

你对反射率做了归一化:

R_s_normalized = (R_s - min(R_s)) / (max(R_s) - min(R_s))
R_p_normalized = (R_p - min(R_p)) / (max(R_p) - min(R_p))

而预期的结果是绝对反射率(不是归一化到0-1的相对值),这会导致你的图和预期图的数值范围完全不同,即使计算正确,视觉上也会有差异。建议直接绘制原始反射率R_sR_p


4. 垂直入射时的冗余计算(可优化)

当入射角为0°时,S偏振和P偏振的反射率是完全相等的,所以你不需要分别计算R_s和R_p,也不需要循环计算折射角(θ₂和θ₃都为0),可以简化代码,减少出错概率。


修正后的代码示例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 读取数据(假设文件列:波长、n、k)
Thin_film = pd.read_csv("Si_refractive index.txt", delimiter='\t')
lamb = Thin_film.iloc[:, 0].values
n2 = Thin_film.iloc[:, 1].values
k2 = Thin_film.iloc[:, 2].values
N2 = n2 + 1j * k2

# 参数设置
d = 200  # 薄膜厚度,nm
ang_1_s = 0  # 入射角,度
ang_1 = ang_1_s * np.pi / 180  # 转弧度

# 垂直入射时,S和P偏振反射率一致,只需计算一种即可
R = np.zeros(len(lamb))
N1 = 1.0  # 空气折射率
N3 = 1.0  # 空气折射率

for i in range(len(lamb)):
    # 菲涅耳反射系数(垂直入射时S和P偏振系数大小相等)
    r12 = (N1 - N2[i]) / (N1 + N2[i])
    r23 = (N2[i] - N3) / (N2[i] + N3)
    
    # 相位差δ(往返相位变化)
    delta = (4 * np.pi * d / lamb[i]) * N2[i]
    
    # 总反射系数
    r_total = (r12 + r23 * np.exp(2j * delta)) / (1 - r12 * r23 * np.exp(2j * delta))
    
    # 反射率(绝对值平方)
    R[i] = np.abs(r_total) ** 2

# 绘图
plt.title(f"反射率 φ={ang_1_s}°")
plt.xlim(300, 1000)
plt.xlabel("波长 (nm)")
plt.ylabel("反射率")
plt.plot(lamb, R, label="S/P 偏振(垂直入射一致)")
plt.legend()
plt.show()

额外说明

垂直入射时,S和P偏振的反射率完全相同,所以预期图中两条曲线是重合的,修正后的代码会得到和预期一致的结果。另外,确保你的硅折射率数据是正确的(包含n和k随波长的变化),这也是结果准确的前提。

备注:内容来源于stack exchange,提问作者Pxndx

火山引擎 最新活动