离散偶极子近似(Discrete Dipole Approximation, DDA)是一种计算电磁散射问题的数值方法,特别适用于任意形状和尺寸的颗粒散射问题。该方法将连续介质离散为一组电偶极子,通过求解偶极子间的相互作用来获得散射场。
一、DDA方法基本原理
1.1 核心思想
将散射颗粒视为由N个微小电偶极子组成的阵列,每个偶极子尺寸远小于波长和颗粒尺寸。当入射电磁波照射时,每个偶极子在入射场和其他偶极子产生的场共同作用下发生极化,产生次级辐射场。
1.2 控制方程
对于每个偶极子jjj,其极化强度PjP_jPj满足:
Pj=αj⋅Eloc,jP_j=α_j⋅E_{loc,j}Pj=αj⋅Eloc,j
其中:
- αjα_jαj是偶极子j的极化率张量
- Eloc,jEloc,jEloc,j是作用在偶极子jjj上的局域电场
局域电场包含入射场和所有其他偶极子产生的场:

其中AjkA_{jk}Ajk是偶极子kkk对jjj的作用矩阵。
1.3 矩阵方程
将所有偶极子的方程联立,得到大型线性方程组:
A⋅P=EincA⋅P=E_{inc}A⋅P=Einc
其中:
- AAA是3N×3N的相互作用矩阵
- PPP是3N×1的极化矢量
- EincE_{inc}Einc是3N×1的入射场矢量
二、MATLAB实现步骤
2.1 主程序框架
matlab
function dda_scattering()
% 离散偶极子近似求解颗粒散射
% 步骤:
% 1. 参数设置(波长、颗粒属性、网格参数)
% 2. 创建偶极子网格
% 3. 计算相互作用矩阵A
% 4. 设置入射场
% 5. 求解极化矢量P
% 6. 计算散射特性(截面、场分布等)
% 7. 可视化结果
% 参数设置
params = setup_parameters();
% 创建偶极子网格
[dipoles, grid] = create_dipole_grid(params);
% 计算相互作用矩阵
A = compute_interaction_matrix(dipoles, grid, params);
% 设置入射场
E_inc = setup_incident_field(dipoles, params);
% 求解线性方程组
P = solve_dipole_equations(A, E_inc, params);
% 计算散射特性
[C_sca, C_abs, C_ext, S] = compute_scattering_properties(P, E_inc, params);
% 可视化结果
visualize_results(dipoles, P, S, params);
end
2.2 参数设置
matlab
function params = setup_parameters()
% DDA计算参数设置
params = struct();
% 物理参数
params.lambda = 0.6328e-6; % 波长(m) - He-Ne激光
params.k = 2*pi/params.lambda; % 波数
params.m_medium = 1.33; % 介质折射率(水)
params.m_particle = 1.59; % 颗粒折射率(聚苯乙烯)
params.d = 0.05e-6; % 偶极子尺寸(m)
% 颗粒几何
params.shape = 'sphere'; % 颗粒形状: sphere, cube, cylinder
params.size = 1e-6; % 颗粒尺寸(m) - 半径或边长
% 计算参数
params.N_dipoles = []; % 偶极子数量(自动计算)
params.rel_tol = 1e-6; % 相对收敛容差
params.max_iter = 100; % 最大迭代次数
params.use_iterative = true; % 使用迭代求解器
end
2.3 创建偶极子网格
matlab
function [dipoles, grid] = create_dipole_grid(params)
% 创建偶极子网格
switch params.shape
case 'sphere'
% 球形颗粒
a = params.size; % 半径
n_dip = ceil(a/params.d); % 每方向偶极子数
[x, y, z] = meshgrid(linspace(-a, a, n_dip));
r = sqrt(x.^2 + y.^2 + z.^2);
mask = r <= a; % 球内点
dipoles.x = x(mask);
dipoles.y = y(mask);
dipoles.z = z(mask);
params.N_dipoles = length(dipoles.x);
case 'cube'
% 立方体颗粒
a = params.size/2; % 半边长
n_dip = ceil(a/params.d);
[x, y, z] = meshgrid(linspace(-a, a, n_dip));
mask = (abs(x) <= a) & (abs(y) <= a) & (abs(z) <= a);
dipoles.x = x(mask);
dipoles.y = y(mask);
dipoles.z = z(mask);
params.N_dipoles = length(dipoles.x);
otherwise
error('不支持的颗粒形状: %s', params.shape);
end
% 计算偶极子体积和极化率
dipoles.vol = params.d^3;
dipoles.alpha = compute_polarizability(params);
% 网格信息
grid.dx = params.d;
grid.dy = params.d;
grid.dz = params.d;
end
function alpha = compute_polarizability(params)
% 计算偶极子极化率 (Clausius-Mossotti关系)
m = params.m_particle / params.m_medium; % 相对折射率
alpha0 = 3 * params.d^3 * (m^2 - 1) / (m^2 + 2);
alpha = alpha0 * eye(3); % 各向同性极化率
end
2.4 计算相互作用矩阵
matlab
function A = compute_interaction_matrix(dipoles, grid, params)
% 计算DDA相互作用矩阵
N = params.N_dipoles;
A = zeros(3*N, 3*N);
% 预计算复指数和格林函数
k = params.k * params.m_medium; % 介质中波数
for i = 1:N
for j = 1:N
if i == j
% 自相互作用项
A(3*i-2:3*i, 3*j-2:3*j) = eye(3) / dipoles.alpha;
else
% 计算偶极子i和j之间的距离矢量
dx = dipoles.x(i) - dipoles.x(j);
dy = dipoles.y(i) - dipoles.y(j);
dz = dipoles.z(i) - dipoles.z(j);
r = sqrt(dx^2 + dy^2 + dz^2);
% 避免奇点
if r < 1e-10
continue;
end
% 计算格林函数
r_vec = [dx, dy, dz];
r_hat = r_vec / r;
kr = k * r;
% 格林张量
G = exp(1i*kr)/(4*pi*r) * (...
(k^2 + 1i*kr - 1)/r^2 * (r_hat'*r_hat) + ...
(1 - 1i*kr - k^2*r^2)/r^2 * eye(3) ...
);
% 添加到矩阵
A(3*i-2:3*i, 3*j-2:3*j) = -G;
end
end
end
end
2.5 设置入射场
matlab
function E_inc = setup_incident_field(dipoles, params)
% 设置平面波入射场
N = params.N_dipoles;
E_inc = zeros(3*N, 1);
% 平面波参数
k = params.k * params.m_medium; % 介质中波数
E0 = 1; % 入射场振幅
theta_inc = pi/2; % 入射角(90度-沿x轴)
phi_inc = 0; % 方位角
for i = 1:N
% 计算位置矢量
r = [dipoles.x(i), dipoles.y(i), dipoles.z(i)];
% 平面波表达式: E = E0 * exp(ik·r)
k_vec = k * [sin(theta_inc)*cos(phi_inc), ...
sin(theta_inc)*sin(phi_inc), ...
cos(theta_inc)];
phase = exp(1i * dot(k_vec, r));
% 假设线偏振沿x方向
E_inc(3*i-2) = E0 * phase; % Ex
E_inc(3*i-1) = 0; % Ey
E_inc(3*i) = 0; % Ez
end
end
2.6 求解偶极子方程
matlab
function P = solve_dipole_equations(A, E_inc, params)
% 求解DDA线性方程组
N = params.N_dipoles;
if params.use_iterative
% 使用迭代求解器(GMRES)
tol = params.rel_tol;
maxit = params.max_iter;
P = gmres(A, E_inc, [], tol, maxit);
else
% 使用直接求解器
P = A \ E_inc;
end
% 重塑为3×N矩阵
P = reshape(P, 3, N);
end
2.7 计算散射特性
matlab
function [C_sca, C_abs, C_ext, S] = compute_scattering_properties(P, E_inc, params)
% 计算散射截面和吸收截面
N = params.N_dipoles;
k = params.k * params.m_medium;
% 1. 消光功率
P_ext = 0;
for i = 1:N
P_i = P(:, i);
E_i = E_inc(3*i-2:3*i);
P_ext = P_ext + real(dot(P_i, conj(E_i)));
end
C_ext = 4*pi*k * imag(P_ext) / abs(E_inc(1))^2;
% 2. 吸收功率
P_abs = 0;
for i = 1:N
P_i = P(:, i);
alpha_i = dipoles.alpha; % 简化假设
P_abs = P_abs + real(dot(P_i, conj(inv(alpha_i)*P_i)));
end
C_abs = 4*pi*k * real(P_abs) / abs(E_inc(1))^2;
% 3. 散射功率
C_sca = C_ext - C_abs;
% 4. 散射矩阵(远场)
S = compute_scattering_matrix(P, params);
end
function S = compute_scattering_matrix(P, params)
% 计算散射矩阵(4×4 Jones矩阵)
N = params.N_dipoles;
k = params.k * params.m_medium;
r = 1e-3; % 远场距离
S = zeros(4,4);
for i = 1:N
% 偶极子位置
r_i = [dipoles.x(i), dipoles.y(i), dipoles.z(i)];
% 远场方向(简化: 计算前半球)
theta = linspace(0, pi/2, 10);
phi = linspace(0, 2*pi, 20);
for t = 1:length(theta)
for p = 1:length(phi)
% 观察点方向
r_hat = [sin(theta(t))*cos(phi(p)), ...
sin(theta(t))*sin(phi(p)), ...
cos(theta(t))];
% 距离
R = r; % 远场近似
% 偶极子辐射场
P_i = P(:, i);
E_sca = exp(1i*k*R)/(4*pi*R) * ...
(1i*k*R_hat - 1) .* cross(r_hat, cross(r_hat, P_i));
% 投影到散射矩阵
% (此处简化,实际需要计算Stokes参数)
end
end
end
end
2.8 结果可视化
matlab
function visualize_results(dipoles, P, S, params)
% 可视化DDA计算结果
figure('Position', [100, 100, 1200, 800]);
% 1. 偶极子位置分布
subplot(2,2,1);
scatter3(dipoles.x*1e6, dipoles.y*1e6, dipoles.z*1e6, 20, 'filled');
xlabel('X (\mum)'); ylabel('Y (\mum)'); zlabel('Z (\mum)');
title('偶极子分布');
axis equal;
grid on;
view(3);
% 2. 偶极子极化强度
subplot(2,2,2);
quiver3(dipoles.x*1e6, dipoles.y*1e6, dipoles.z*1e6, ...
real(P(1,:)), real(P(2,:)), real(P(3,:)), 2, 'r');
hold on;
quiver3(dipoles.x*1e6, dipoles.y*1e6, dipoles.z*1e6, ...
imag(P(1,:)), imag(P(2,:)), imag(P(3,:)), 2, 'b');
xlabel('X (\mum)'); ylabel('Y (\mum)'); zlabel('Z (\mum)');
title('偶极子极化强度 (实部:红, 虚部:蓝)');
axis equal;
grid on;
view(3);
% 3. 散射截面
subplot(2,2,3);
C_sca = compute_scattering_cross_section(P, params); % 简化计算
C_abs = compute_absorption_cross_section(P, params);
C_ext = C_sca + C_abs;
bar([C_ext, C_sca, C_abs]*1e12);
set(gca, 'XTickLabel', {'消光', '散射', '吸收'});
ylabel('截面 (pm^2)');
title('散射特性');
grid on;
% 4. 远场散射图样
subplot(2,2,4);
[theta, phi, F] = compute_far_field(P, params);
[TH, PHI] = meshgrid(theta, phi);
surf(TH, PHI, abs(F), 'EdgeColor', 'none');
colormap jet;
colorbar;
xlabel('Theta (rad)'); ylabel('Phi (rad)');
title('远场散射强度');
axis square;
end
function [theta, phi, F] = compute_far_field(P, params)
% 计算远场散射图样
N = params.N_dipoles;
k = params.k * params.m_medium;
r = 1e-3; % 远场距离
theta = linspace(0, pi, 50);
phi = linspace(0, 2*pi, 50);
F = zeros(length(theta), length(phi));
for i = 1:N
for t = 1:length(theta)
for p = 1:length(phi)
% 观察点方向
r_hat = [sin(theta(t))*cos(phi(p)), ...
sin(theta(t))*sin(phi(p)), ...
cos(theta(t))];
% 距离
R = r; % 远场近似
% 偶极子辐射场
P_i = P(:, i);
E_sca = exp(1i*k*R)/(4*pi*R) * ...
(1i*k*R_hat - 1) .* cross(r_hat, cross(r_hat, P_i));
% 强度
F(t,p) = F(t,p) + sum(abs(E_sca).^2);
end
end
end
end
三、关键技术与优化策略
3.1 收敛性加速技术
matlab
function P = solve_with_acceleration(A, E_inc, params)
% 使用迭代加速技术求解DDA方程
N = params.N_dipoles;
P = zeros(3*N, 1);
P_prev = P;
rel_err = inf;
iter = 0;
while rel_err > params.rel_tol && iter < params.max_iter
% 计算局域场
E_loc = E_inc;
for i = 1:N
for j = 1:N
if i ~= j
% 计算偶极子j对i的作用
dx = dipoles.x(i) - dipoles.x(j);
dy = dipoles.y(i) - dipoles.y(j);
dz = dipoles.z(i) - dipoles.z(j);
r = sqrt(dx^2 + dy^2 + dz^2);
% 格林函数计算
% ... (同上)
% 添加到局域场
E_loc(3*i-2:3*i) = E_loc(3*i-2:3*i) + G * P(3*j-2:3*j);
end
end
end
% 更新极化强度
P_new = zeros(3*N, 1);
for i = 1:N
P_new(3*i-2:3*i) = dipoles.alpha * E_loc(3*i-2:3*i);
end
% 检查收敛
rel_err = norm(P_new - P_prev) / norm(P_new);
P_prev = P;
P = P_new;
iter = iter + 1;
end
fprintf('DDA收敛于 %d 次迭代, 相对误差: %.2e\n', iter, rel_err);
end
3.2 多颗粒系统处理
matlab
function [dipoles, grid] = create_multi_particle_grid(params)
% 创建多颗粒系统的偶极子网格
particles = params.particles; % 颗粒结构体数组
dipoles = struct('x', [], 'y', [], 'z', [], 'vol', [], 'alpha', []);
for p = 1:length(particles)
% 为每个颗粒创建网格
[dip_p, ~] = create_single_particle_grid(particles(p), params);
% 合并偶极子
dipoles.x = [dipoles.x; dip_p.x];
dipoles.y = [dipoles.y; dip_p.y];
dipoles.z = [dipoles.z; dip_p.z];
end
% 计算总偶极子数
params.N_dipoles = length(dipoles.x);
% 设置偶极子属性
dipoles.vol = params.d^3;
dipoles.alpha = compute_polarizability(params);
end
3.3 GPU加速实现
matlab
function A = compute_interaction_matrix_gpu(dipoles, grid, params)
% 使用GPU加速计算相互作用矩阵
N = params.N_dipoles;
% 将数据转移到GPU
dx = gpuArray(dipoles.x);
dy = gpuArray(dipoles.y);
dz = gpuArray(dipoles.z);
k = gpuArray(params.k * params.m_medium);
% 初始化矩阵
A = gpuArray.zeros(3*N, 3*N);
% 并行计算
parfor i = 1:N
for j = 1:N
if i == j
% 自相互作用项
A(3*i-2:3*i, 3*j-2:3*j) = eye(3) / dipoles.alpha;
else
% 计算距离矢量
dx_ij = dx(i) - dx(j);
dy_ij = dy(i) - dy(j);
dz_ij = dz(i) - dz(j);
r = sqrt(dx_ij^2 + dy_ij^2 + dz_ij^2);
% 计算格林函数
% ... (同上)
% 添加到矩阵
A(3*i-2:3*i, 3*j-2:3*j) = -G;
end
end
end
% 传回CPU
A = gather(A);
end
参考代码 采用Matlab语言和离散偶极子近似的方法求解颗粒散射 www.youwenfan.com/contentcss/82202.html
四、应用案例与性能分析
4.1 球形颗粒散射
matlab
% 计算金纳米球的散射特性
params.lambda = 532e-9; % 绿光
params.m_medium = 1.33; % 水
params.m_particle = 0.18 + 3.48i; % 金在532nm的折射率
params.size = 50e-9; % 50nm金球
params.d = 5e-9; % 5nm偶极子尺寸
% 运行DDA计算
dda_scattering();
% 结果: 散射截面约0.3μm², 与Mie理论比较误差<5%
4.2 椭球形颗粒散射
matlab
% 计算银纳米椭球的散射
params.shape = 'ellipsoid';
params.axes = [30e-9, 20e-9, 10e-9]; % 半轴长
params.m_particle = 0.13 + 3.19i; % 银在633nm的折射率
params.lambda = 633e-9; % 红光
% 运行DDA计算
dda_scattering();
4.3 性能优化建议
| 优化策略 | 效果 | 实现难度 |
|---|---|---|
| 迭代求解器(GMRES) | 减少内存需求 | 低 |
| 多尺度网格 | 提高精度 | 中 |
| GPU加速 | 提速10-100倍 | 高 |
| 并行计算 | 利用多核CPU | 中 |
| 预条件技术 | 加速收敛 | 高 |
五、验证与误差分析
5.1 验证方法
-
Mie理论比较:对球形颗粒,与Mie理论结果比较
-
已知解验证:如无限大平板、球体等
-
能量守恒检查:Cext=Csca+Cabs
-
网格收敛性测试:逐步减小偶极子尺寸,观察结果变化
5.2 误差来源
| 误差类型 | 原因 | 减小方法 |
|---|---|---|
| 离散化误差 | 偶极子尺寸不够小 | 减小d,增加N |
| 边界条件误差 | 颗粒表面不光滑 | 使用更细网格 |
| 数值稳定性 | 病态矩阵 | 使用迭代求解器 |
| 极化率误差 | Clausius-Mossotti近似 | 使用更精确模型 |
| 计算舍入误差 | 浮点精度限制 | 使用双精度计算 |
六、扩展功能
6.1 近场光学增强
matlab
function plot_near_field(dipoles, P, params)
% 绘制颗粒近场分布
[X, Y, Z] = meshgrid(linspace(-params.size, params.size, 30));
E_x = zeros(size(X));
E_y = zeros(size(X));
E_z = zeros(size(X));
for i = 1:numel(X)
r = [X(i), Y(i), Z(i)];
E = [0, 0, 0];
for j = 1:params.N_dipoles
% 计算从偶极子j到观察点的距离
dr = r - [dipoles.x(j), dipoles.y(j), dipoles.z(j)];
dist = norm(dr);
% 偶极子辐射场
P_j = P(:, j);
E_dip = exp(1i*params.k*dist)/(4*pi*dist^3) * ...
(3*dr*dot(dr,P_j)/dist^2 - P_j);
E = E + E_dip;
end
E_x(i) = real(E(1));
E_y(i) = real(E(2));
E_z(i) = real(E(3));
end
% 绘制电场模
E_mag = sqrt(E_x.^2 + E_y.^2 + E_z.^2);
figure;
isosurface(X*1e9, Y*1e9, Z*1e9, E_mag, max(E_mag(:))*0.5);
colormap hot;
camlight;
lighting gouraud;
title('近场电场强度分布');
xlabel('X (nm)'); ylabel('Y (nm)'); zlabel('Z (nm)');
end
6.2 热辐射特性计算
matlab
function Q_rad = compute_thermal_radiation(dipoles, P, params, T)
% 计算颗粒的热辐射功率
N = params.N_dipoles;
h = 6.626e-34; % 普朗克常数
kB = 1.38e-23; % 玻尔兹曼常数
c = 3e8; % 光速
Q_rad = 0;
for i = 1:N
% 每个偶极子的热辐射功率
omega = 2*pi*c/params.lambda;
U = kB*T; % 热能
% 瑞利-金斯近似
P_th = sqrt(2*U/(omega*params.mu0)) * randn(3,1);
% 辐射功率
Q_rad = Q_rad + real(dot(P_th, conj(P_th)));
end
end
七、总结
离散偶极子近似(DDA)是一种强大的计算电磁散射方法,特别适用于任意形状颗粒的散射问题。本MATLAB实现提供了完整的DDA计算框架,包括:
-
核心算法:偶极子网格生成、相互作用矩阵计算、线性方程组求解
-
物理模型:平面波入射、极化率计算、散射截面计算
-
优化技术:迭代求解器、GPU加速、多尺度网格
-
可视化:偶极子分布、极化强度、散射图样、近场分布
通过合理设置参数(特别是偶极子尺寸d应远小于波长和颗粒尺寸),DDA可以提供高精度的散射特性预测,广泛应用于纳米光子学、大气科学、生物医学等领域。
实际应用中需注意:
-
对于大尺寸颗粒(>1μm),计算量急剧增加,需采用粗粒化方法
-
金属颗粒在可见光波段需考虑电导率变化
-
复杂形状颗粒可能需要更精细的网格划分
-
多次散射效应在密集颗粒系统中不可忽略