第5節.均勻各向同性介質中單色標量光場的傳播
這節課,我們來看看怎麼模擬光在均勻各向同性介質中的傳播過程。會了這節課,你就可以模擬一些特殊光束的傳播特性,例如:艾里光,徑向艾里光,渦旋光等。這節的光就是跟題目說的一樣:單色標量光場。
1.傅里葉變換正基
我這裡定義的
正頻率時域諧波對應的時域表示 =>
正頻率空域諧波對應的時域表示 =>
正頻率時空域諧波對應的時域表示 =>
2.單色標量光場的表示
標量:不考慮偏振態,假設各處偏振都是一樣的。
單色:光學頻率為單一值。
標量光場可以用 表示,如果是一個處處都是時域單色諧波,那麼我們對時域做傅里葉變換,就可以得到頻率域的兩個尖峰非零值。我們取正頻率處的非零值 來描述該處的光場。也就是說,我們光場做了個時域傅里葉變換,然後那個超級窄帶濾波器濾了出來。
而我們要求解的問題就是,已知 ,求 。
3. 光的傳播
均勻線性介質中有
在各項同性介質中有
基本的原理弄完了,下面開始寫代碼。
function var = space(varargin)
% 創建變數空間
% para = space(dimension1,window1,sample1,dimension2,window2,sample2,...)
% 輸入
% dimension - 維度 (字元串),可取x 、 y、t
% window - 範圍
% sample - 採樣個數
%
% 輸出
% var - 變數空間
% 如果不定義某維度,則定義該維度window = 0,sample =1
[var.x_,var.fx_]=domain(0,0);
[var.y_,var.fy_]=domain(0,0);
[var.t_,var.ft_]=domain(0,0);
for index_var =1:3:length(varargin)
key = varargin{index_var};
try
window = varargin{index_var+1};
sample = varargin{index_var+2};
catch
error([unenougth parm for: ,key])
end
switch key
case x
[var.x_,var.fx_]=domain(window,sample);
case y
[var.y_,var.fy_]=domain(window,sample);
case t
[var.t_,var.ft_]=domain(window,sample);
otherwise
error([undefine key : ,key])
end
end
[var.x,var.y,var.t] = meshgrid(var.x_,var.y_,var.t_);
[var.fx,var.fy,var.ft] = meshgrid(var.fx_,var.fy_,var.ft_);
第一個代碼是用來創建變數空間,就是利用第1節.Matlab中的fft的函數重建多維空間,這個最多創建三維空間xyt, 但是這節只需要使用xy.
下面代碼是模擬高斯光束經過透鏡的聚焦過程。
clc
clear
units
%%
lambda = 1560*nm;
var = space(x,10*mm,256,y,10*mm,256);
var.ft = var.ft+c./lambda;
%%
kz = 2*pi*sqrt((var.ft/c).^2-(var.fx).^2-(var.fy).^2);
w0 = 1.5*mm;
E = exp(-(var.x/w0).^2).*exp(-(var.y/w0).^2);
subplot(1,3,1)
imagesc(fftshift(var.x_)/mm,fftshift(var.y_)/mm,fftshift(abs(E).^2));
colormap gray
axis xy
title(輸入)
Focus_length = 25*cm;
Fai_len = 2*pi*var.ft./c.*(var.x.^2+var.y.^2)/2/(Focus_length);
STEP = 1:500;
dz = 2*Focus_length./length(STEP);
GPU_ON = 1;
%% 初始化光場
if(GPU_ON)
Ez = gpuArray(E.*exp(i*Fai_len));
P = gpuArray( exp(-i*kz.*dz));
section = gpuArray(zeros(length(var.y_),length(STEP)));
else
Ez = (E.*exp(i*Fai_len));
P = ( exp(-i*kz.*dz));
section = (zeros(length(var.y_),length(STEP)));
end
%% 模擬主程序
tic
for index = STEP
Ez = fft2(P.*ifft2(Ez));
section(:,index) = Ez(:,1);
end
toc
%%
subplot(1,3,2)
imagesc(fftshift(var.x_)/mm,fftshift(var.y_)/mm,fftshift(abs(Ez).^2));
colormap gray
axis xy
title(輸出)
subplot(1,3,3)
imagesc(STEP*dz/mm,fftshift(var.y_)/mm,(abs(fftshift(section,1))));
colormap gray
axis xy
title(截面)
然後我們把透鏡相位去掉,然後把入射光束的寬度調小一點。可以看到衍射。
你們可以初始化出不同的初始光場,例如經過兩個狹縫。
最後,如果有大神看到這篇文章,我有個問題想請教一下:
在我的電腦上,如果使用gpuArray來做迭代,在STEP比較小的是可以加速的。但是隨著迭代次數的提高,似乎耗時越來越長。我不太能理解。有沒有大神能解答一下!使用的顯卡是Quadro K600。下圖是把每次迭代的時間記錄下來的圖。可以看到118次處,使用gpuArray的曲線有個拐點。
我想問~這個是什麼原因導致的,有辦法避免嗎?
下面代碼為測試代碼(因為前面的代碼需要額外的外部m文件,把步驟實現了),複製到matlab中應該可以直接運行。
clc
clear
%%
matrix_size = 256;
Fai_len = rand(matrix_size);
E = rand(matrix_size);
kz = rand(matrix_size);
dz = 1;
STEP = 1:500;
TOC1 = zeros(size(STEP));
TOC2 = zeros(size(STEP));
%% 沒有GPU加速
Ez = E.*exp(i*Fai_len);
P = exp(-i*kz.*dz);
section = zeros(matrix_size,length(STEP));
tic
for index = STEP
Ez = fft2(P.*ifft2(Ez));
section(:,index) = Ez(:,1);
TOC1(index) = toc;
end
%% 有GPU加速
Ez = gpuArray(E.*exp(i*Fai_len));
P = gpuArray(P);
section = gpuArray(section);
tic
for index = STEP
Ez = fft2(P.*ifft2(Ez));
section(:,index) = Ez(:,1);
TOC2(index) = toc;
end
%%
plot(TOC1);
hold on
plot(TOC2);
hold off
推薦閱讀:
TAG:MATLAB |