激光能量分佈仿真分析

前言

  當代科技最核心的器件是什麼?答案毋庸置疑,激光器。那麼你瞭解激光嗎?本文將從最本質的角度帶你深入瞭解激光的形成,以及諧振腔如何影響激光的能量分佈。

激光形成的簡述

  無論什麼樣的激光器都必須在諧振腔內產生激光,一方面是不斷給諧振腔充能,另一方面是使用光子去誘發一個同頻率光子的產生,此後越來越多的光子(並且是同頻率同相位的)在激光器的諧振腔內往復運動,進而激光的能量也就越來越大,然後選擇在某一瞬間釋放這股能量,這就是我們所看到的激光。
  因此,激光的能量分佈(術語稱之爲激光的橫模模式)也是受諧振腔的影響而相應變化的。

程序

  下面兩個程序用簡單的方法實現仿真,算法的時間複雜度極高,且沒有在編程技巧上進行改進,因此需要運行較長時間。在最後,我改進了變成技巧,加速了程序的運行。初寫這類仿真程序時,用的是matlab。然而離開學校以後,價格高昂的matlab軟件不再能使用。因此,用Python補充這些程序。如果有讀者想要討論電磁場理論相關的物理學或者編程以及數學,我的郵箱是[email protected]

python程序

#---------------^_^-------------^_^-------
#利用python仿真雙縫實驗
#程序再版與2019/1/5,初版寫於2017年12月
#作者:cclplus
#僅供學習交流使用
#如有疑問或者需求,可以聯繫作者[email protected]

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math

n=int(50)    #方鏡上點的個數
rd=0.005#方鏡的邊長——單位m
ld=1.0  #確定諧振腔的腔長
#假設起始時光強處處相等
I=np.ones((n,n),float)
#這是一個需要長時間運行的程序
for t in range(30):
    In=np.zeros((n,n),float)
    for i in range(n):
        for j in range(n):
            for i1 in range(n):
                for j1 in range(n):
                    In[i][j]=In[i][j]+1.0/(4.0*math.pi)*I[i1][j1]*\
                    (1.0+ld/math.sqrt((rd/float(n)*(i1-i))**2+\
                    (rd/float(n)*(j1-j))**2+ld**2))\
                    /float(n)/float(n)
    I=In*[1.0]

S_I=sum(sum(I[i]) for i in range(len(I))) 
mul=float(n)*float(n)/S_I
I*=[mul]
I*=I
fig = plt.figure()
ax = Axes3D(fig)
X=range(n)
Y=range(n)
ax.plot_surface(X, Y, I, rstride=1, cstride=1, cmap='rainbow')
plt.show()

matlab程序

%作者:cclplus
%時間:2017年12月
clc
clear all;
close all;
%%%%%以下程序用於建立反射鏡的模型top
%%%方形鏡
n=50;%取點,確定精度
rd=0.005;%確定方形鏡的邊長
ld=1;%確定諧振腔的長度
%%%%以上程序用於建立反射鏡的模型bottom
I=ones(n,n);%假設初始光強處處相等
for t=1:50
In=zeros(n,n);
for i=1:n
    for j=1:n
        for i1=1:n
            for j1=1:n
                In(i,j)=In(i,j)+1/(4*pi)*I(i1,j1)*(1+ld/sqrt((rd/n*(i1-i))^2+(rd/n*(j1-j))^2+ld^2))*1/2500;
            end
        end
    end
end
I=In;
end
%%%bottom
S_I=sum(sum(In)');
multipe=n^2/S_I;
I=multipe.*In;
%當找到有一組不符合的數據,即可跳出
%繪製圖像
x=1:n;
y=1:n;
I=I.^2;
surf(x,y,I);
shading interp
axis equal

##實驗結果圖

在這裏插入圖片描述
  受衍射的影響,激光的能量逐漸集中

對程序的改進

  我想有的人通過Python執行這段程序的時候,估計要懷疑計算機死機了,這確實是個問題,我在第一次寫作時確實是等待了很長的運行時間,然後再把圖片保存下來。
想要改進這個程序,需要採用動態鏈接庫(dll)的方法

#---------------^_^-------------^_^-------
#利用python仿真雙縫實驗
#程序再版與2019/1/5,初版寫於2017年12月
#作者:cclplus
#僅供學習交流使用
#如有疑問或者需求,可以聯繫作者[email protected]

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
from ctypes import *
#dll = cdll.LoadLibrary('laser.dll');
dll=WinDLL('laser.dll')
class StructPointer(Structure):  
    _fields_ = [("arr", c_double * 2500)] 
    def __init__( self ):
        for i in range(2500):
            self.arr[i]=0.0
dll.laser_mode.restype = POINTER(StructPointer) 
n=c_long(50)    #方鏡上點的個數
n_b=int(50)
k=c_long(30)
#ccl=np.ones((n,n),float)
ccl=StructPointer()
#dll.hello()
ccl=dll.laser_mode(n,k)
I=np.zeros((n_b,n_b),float)
for i in range(n_b):
    for j in range(n_b):
        I[i][j]=ccl.contents.arr[i*n_b+j]
X=range(n_b)
Y=range(n_b)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X,Y,I, rstride=1, cstride=1, cmap='rainbow')
plt.show()

想要獲取更詳細的相關資料可以訪問我的github主頁https://github.com/YuruTu/laser

算法上的改進

  一力降十會,在絕對力量的面前,再多的技巧也只能黯然失色。很多時候改進算法纔是改良計算機程序的根本。個人認爲真正的簡化這個過程在於數學公式的推導。曹三鬆在《穩定腔激光模式理論的再研究》中推導了這個過程,並得出結論
共焦腔鏡面上激光場振幅的表達式爲

其中 C表示歸一化係數,H表示Hermite多項式
光強I正比於光場振幅的平方
對推導過程持懷疑態度的讀者可以聯繫本文作者cclplus,我會竭力爲您解答
以下代碼爲小斐而寫(如果有需要,我可以把這個程序打包成GUI模式)


#寫作時間:2019年2月26日
#爲小斐而寫
#作者cclplus
import sympy#sympy的安裝過程特殊,必須通過先在官網下載.gz文件
import matplotlib.pyplot as plt
import math
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
eps = 0.001
#定義一個函數用於求Hermite多項式的平方值
#往後求導過程比較繁瑣,暫不加以推廣
def heimite(n,x):
    if n==0:
        return 1
    elif n==1:
        return 4.0*x*x
    elif n==2:
        return (4.0*x*x-2.0)*(4.0*x*x-2.0)
    elif n==3:
        return (12.0*x-8.0*x**3.0)**2.0
    else:
        print("暫時不支持計算比3更大的Hermite多項式的平方值\n\
            聯繫作者獲得相關支持")

if __name__ == "__main__":
    #沒有用上全部參數,但也足以說明問題
    num_plot = 200
    m = 3
    n = 3
    R=np.zeros((num_plot,num_plot),float)
    for i in range( num_plot):
        for j in range( num_plot):
            x =float(i-num_plot/2)/float(num_plot/10)
            y =float(j-num_plot/2)/float(num_plot/10)
            R[i][j] =heimite(m,x)*heimite(n,y)*sympy.exp(-2.0*x*x-2.0*y*y)
    fig = plt.figure()

    X=range(num_plot)
    Y=range(num_plot)
    plt.contourf(X, Y, R, 8, alpha = 0.75, cmap = plt.cm.hot)
    plt.show()

結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章