はじめに
レーザーに関係する仕事や研究を行っているとレーザービーム品質の指標の一つM²(エムスクエア)といった用語を聞くことがあると思う。このM²はレーザーの広がり角や集光サイズにダイレクトに効いてくる因子であり、レーザー装置を使う場面においては重要な要素の一つである。
もともとM²の解説記事としては平等先生の非常に読みやすい記事[1]があるため、わざわざ別の記事を別途書く必要はないと感じていた。しかし、最近になって自分の仕事上M²のより詳しい検討の必要がでてきたので自分の理解がてら備忘録的に記事にまとめる。
本解説記事ではレーザービーム品質の定義を解説記事を説明し、Juliaによる計算結果を同時に示すことでより実践的にわかりやすくした。juliaの記事なども書いています。
ビーム品質 : M²
繰り返しになるが、M²の解説については平等先生の解説記事[1]を読むことを強く勧めたい。日本語記事の解説記事でここまで丁寧にわかりやすく書いている記事はあまり多くない。ここでは詳細な数学的記述は元記事に譲ってエッセンスだけ抜き出したい。一部理解の優先のため、天下り的な記述にしている。
一般に最もビーム品質が高いとされる場合は基本ガウシアンビームと呼ばれたりする。このモードのビームプロファイルは読んで字のごとくガウシアン分布になっている。一方、ビーム品質が低いとされる場合は高次の横モードになっている、あるいは混合している。高次ガウスビーム(ビーム品質が低い)半径\(w_{high}(z)\)は、基本ガウシアンビーム半径\(w_{normal}(z)\)と比較して、\(M\)倍大きいとする。 \begin{equation} w_{high}(z) = M w_{normal}(z) \end{equation} また、Hermholz方程式を解くことによって得られる複素ビームパラメータ – \( q\)パラメータ(今回の解説記事[1]のほかにYarivの教科書[2]などで詳細に解説がされている。)は真空中で次のように表される。 \begin{equation} \frac{1}{q(z)} = \frac{1}{R(z)} – i \frac{\lambda}{\pi w_{normal}^2(z)} \end{equation} ここで、\(R(z),\lambda\)はそれぞれビームの曲率、ビームの波長である。これが高次ガウスビームの場合を考えると \begin{equation} \frac{1}{q(z)} = \frac{1}{R(z)} – i \frac{M^2 \lambda}{\pi w_{high}(0)^2} \end{equation} 上式が得られる。ここで\(w_{high}(0)\)は高次ガウスビームの集光点での半径である。\( q\)パラメータの実部がビームの曲率、虚部がスポット半径であることが知られているので、 \begin{array} R(z) &= z\left[ 1+ \left( \frac{\pi w_{high}(0)^2}{M^2 \lambda(z-z_0)}\right) \right]\\ W(z) &= w_{high}(0)\sqrt{1+ \left( \frac{M^2 \lambda(z-z_0)}{\pi w_{high}(0)^2}\right)} \end{array} これにより、高次横モードを含むビームサイズは基本モードに比べ\(M\)倍のガウシアン光としてビーム伝搬を記述できることがわかった。
ビームの伝搬の様子をJuliaで計算したので以下の図を参考にしていただきたい。


一枚目のPlotは単純に\(M^2\)を変えたものとなっており、広がり角が遠方において\(M^2\)倍になっていることがわかる。2枚目については同じ広がり角になるように\(w(z=0)\)をリスケールしたものとなっており、出射位置(集光位置)ではM倍のビームサイズになっていることが確認される。
具体的な高次モードとM²の関係性
ここまでの議論はほとんど解説記事に沿ったものだった。この章からは具体的な高次横モードの描像と\(M^2\)の関係性を掘り下げていく。共振器横モードについての考察はこちらの論文[3]で行われている。
Hermite gaussian
共振器の損失が非常に小さいか、ミラーが十分に大きい場合にHermite gaussian(エルミートガウシアン)モードになることが知られている[3]。特にこのモードについては霜田先生による計算がされており、数式の導出はこちら[4]を参考にしてほしい。Hermite gaussian modeの電場\(E_{l,m}\)は次式で表される[2]。
\begin{equation} E_{l,m}(x,y,z) = E_0 \frac{\omega_0}{\omega(z)} H_l\left( \sqrt{2}\frac{x}{\omega(z)} \right) H_m\left( \sqrt{2}\frac{y}{\omega(z)}\right) \\ × \exp \left( -\frac{x^2+y^2}{\omega^2 (z)} -ik\frac{x^2+y^2}{2R(z)}- ikz + i(l+m+1)\eta \right) \end{equation}
ここで\(H,l,m,k,R,\omega,\omega_0,\eta\)はそれぞれエルミート多項式、\(x\)軸方向へのエルミート次数、\(y\)軸方向へのエルミート次数、波数、位相面の曲率、ビーム半径、集光位置でのビーム半径、\(Tan^{-1}(-(z-z₀)/(kω₀^2))\)となっている。
これを実際に計算した結果とJuliaプログラムを以下に示す。Juliaのプログラムにはこちらのサイト(Juliaで特殊関数を使う)を参考にした。

Hermite gaussianは通常、TEM\(_{lm}\)モードと呼ばれ、特にTEM\(_{00}\)モードは基本ガウシアンモードと一致する。
Laguerre gaussian
レーザーの共振器について、回転対称性を精度よく整えた場合にLaguerre gaussian(ラゲール・ガウシアン)モードになることが知られている[5]。Laguerre gaussian modeの電場\(E_{p,m}\)は円筒座標系を用いて次式で表される。
\begin{equation}
E_{p,m}(r,\phi ,z) = E_0 \frac{\omega_0}{\omega(z)} \frac{\sqrt{2}r}{\omega(z)}^{|m|} L_p^{|m|}\left( \frac{2r^2}{\omega^2(z)}\right) \\ × \exp \left( -\frac{r^2}{\omega^2 (z)} -ik\frac{r^2}{2R(z)}- ikz + im\phi +i(2p+|m|+1)eta \right)
\end{equation}
ここで\(L,p,m\)はラゲール陪多項式、ラゲール陪多項式の半径方向の次数、ラゲール陪多項式の方位角方向の次数である。
これを実際に計算した結果とJuliaプログラムを以下に示す。

Laguerre gaussianの場合も\(p=m=0\)の場合は通常ガウシアンに一致することが知られている。
ビームサイズの定義 – D4σ
よく使われるビーム径の定義として、1/e\(^2\)幅といった定義がある。この定義ではレーザーのピークに対して強度が1/e\(^2\)倍になるところまでをビームとしてビーム径を定義している。しかし、この定義は高次のガウシアンモードを考慮する場合、ピーク位置が自明でなかったりして不適なのが直感的にわかる。そこで、ISO規格で定められているビーム径の定義としてD4σといった定義があり、\(x\)方向の半径は次のように表される[6]。
\begin{equation} \sigma_x^2 = \frac{\int_{-\infty}^\infty \int_{-\infty}^\infty(x-x_0)^2 I(x,y) dxdy}{\int_{-\infty}^\infty \int_{-\infty}^\infty I(x,y) dxdy} \end{equation}
ここでビーム半径\(w\)は以下の様に定義される。
\begin{equation}2\sigma_x = w_x\end{equation}
こちらについて、Juliaで実装したコードを次に示す。また、基本ガウシアンの1/e\(^2\)幅と一致することが知られているので、ここでは一致しているかを確認している。
高次ガウシアンのM²について
最後に、高次ガウシアンモードのM²を計算したのでその結果を乗せる。
Type
l または p
m
M\(_x\)
M\(_y\)
Hermite
0
0
1.00
1.00
Hermite
0
1
1.73
1.00
Hermite
0
2
2.24
1.00
Hermite
0
3
2.65
1.00
Hermite
1
0
1.41
1.41
Hermite
1
1
2.45
1.41
Hermite
1
2
3.16
1.41
Hermite
1
3
3.74
1.41
Hermite
2
0
2.24
2.24
Hermite
2
1
3.87
2.24
Hermite
2
2
5.00
2.24
Hermite
2
3
5.92
2.24
Hermite
3
0
3.16
3.16
Hermite
3
1
5.48
3.16
Hermite
3
2
7.07
3.16
Hermite
3
3
8.37
3.16
Laguerre
0
0
1.00
1.00
Laguerre
0
1
1.22
1.22
Laguerre
0
2
1.34
1.34
Laguerre
0
3
1.13
1.13
Laguerre
1
0
1.41
1.41
Laguerre
1
1
1.73
1.73
Laguerre
1
2
1.90
1.90
Laguerre
1
3
1.60
1.60
Laguerre
2
0
2.24
2.24
Laguerre
2
1
2.74
2.74
Laguerre
2
2
3.01
3.01
Laguerre
2
3
2.52
2.52
Laguerre
3
0
3.16
3.16
Laguerre
3
1
3.87
3.87
Laguerre
3
2
4.25
4.25
Laguerre
3
3
3.57
3.57
参考文献
Juliaコード一覧
M2によるビーム径の変化とモジュールのimport
using SpecialPolynomials
using Polynomials
using Latexify
using LaTeXStrings
using PyPlot
using CSV
using DataFrames
using QuadGK
# calculation beam size depemd on M2
function beam_waist_calcuation(M2, rin, z)
# this calculation is considered as High order Gaussian beam
# We can not use q-prameter because q-parameter is only for 1st order Gaussian beam
# unit is um
λ = 1
w = rin*sqrt(1+(M2*λ*z/(π*rin^2))^2) # beam size
return w
end
z_list = range(0, 100, length=100)
rin = 2
w_1 = map(z -> beam_waist_calcuation(1, rin, z), z_list)
w_2 = map(z -> beam_waist_calcuation(1.5, rin, z) , z_list)
figure()
plot(z_list, w_1, label="M2 = 1")
plot(z_list, w_2, label="M2 = 1.5")
text(100,w_1[end], L"\theta", fontsize=12)
text(100,w_2[end], L"M^2\theta", fontsize=12)
xlabel("z [um]")
ylabel("w [um]")
title("Beam size depend on M2 - when rin size is same")
ylim(0)
legend()
grid()
display(gcf())
z_list = range(0, 150, length=100)
w_1 = map(z -> beam_waist_calcuation(1, 2, z), z_list)
w_2 = map(z -> beam_waist_calcuation(1.5, 2*sqrt(1.5^2), z), z_list)
figure()
plot(z_list, w_1, label="M2 = 1")
plot(z_list, w_2, label="M2 = 1.5")
text(0,w_1[1], L"w", fontsize=12)
text(0,w_2[1], L"Mw", fontsize=12)
xlabel("z [um]")
ylabel("w [um]")
title("Beam size depend on M2 - when divergence angle is same")
ylim(0)
legend()
grid()
display(gcf())
高次ガウシアンモードの確認
function Hermite_gaussian(x , y, z, l, m)
# parameters
k = 1
z₀ = 0
ω₀ = 1
η = atan(-(z-z₀)/(k*ω₀^2))
E₀ = 1
ω_z = ω₀/cos(η)
Eₗₘ = (
E₀ * (ω₀/ω_z) * basis(Hermite, l)(√2*x/ω_z) * basis(Hermite, m)(√2*y/ω_z)
* exp(complex( -(x^2 + y^2)/(ω_z^2), -k*z+(l+m+1)*η) )
)
return Eₗₘ
end
function Laguerre_gaussian(x,y,z,p,m)
# cluculation cylinderical coordinates
r = sqrt(x^2 + y^2)
ϕ = atan(y, x)
# parameters
k = 1
z₀ = 0
ω₀ = 1
η = atan(-(z-z₀)/(k*ω₀^2))
E₀ = 1
ω_z = ω₀/cos(η)
Eₚₘ = (
E₀ * (ω₀/ω_z) * (√2r/ω_z)^abs(m) * basis(Laguerre{m}, p)(√2*r/ω_z)
* exp(complex( -r^2/(ω_z^2), -k*z + m*ϕ + (2p + abs(m) + 1)*η) )
)
return Eₚₘ
end
# D4σの計算 at julia my cord
function D4σ_switch(z, l, m, x₀, y₀, mode)
if mode == "Hermite"
E = Hermite_gaussian
elseif mode == "Laguerre"
E = Laguerre_gaussian
else
error("mode must be 'Hermite' or 'Laguerre'")
end
I(x, y) = abs2(E(x, y, l, m, z))
σ_x_numerator = quadgk(y ->
quadgk(x -> (x - x₀)^2 * I(x, y), -Inf, Inf; maxevals=10^3)[1],
-Inf, Inf; maxevals=10^3)[1]
σ_x_denominator = quadgk(y ->
quadgk(x -> I(x, y), -Inf, Inf; maxevals=10^3)[1],
-Inf, Inf; maxevals=10^3)[1]
σ_x = √( σ_x_numerator / σ_x_denominator )
σ_y_numerator = quadgk(x ->
quadgk(y -> (y - y₀)^2 * I(x, y), -Inf, Inf; maxevals=10^3)[1],
-Inf, Inf; maxevals=10^3)[1]
σ_y_denominator = quadgk(x->
quadgk(y -> I(x, y), -Inf, Inf; maxevals=10^3)[1],
-Inf, Inf; maxevals=10^3)[1]
σ_y = √( σ_y_numerator / σ_y_denominator )
return 2 * σ_x, 2 * σ_y
end
x_max = y_max = 3
x_vals = range(-x_max, x_max, length = 100)
y_vals = range(-y_max, y_max, length = 100)
figure(figsize=(12, 12))
# Calculate Hermite_gaussian 0,0 to 3,3
for l in 0:3
for m in 0:3
Elm = zeros(Complex{Float64}, length(x_vals), length(y_vals))
for i in 1:length(x_vals)
for j in 1:length(y_vals)
Elm[i,j] = Hermite_gaussian(x_vals[i], y_vals[j], 0, l, m)
end
end
# Plotting
subplot(4,4,l*4+m+1)
title("l is $l, m is $m")
imshow(abs2.(Elm), extent = (x_vals[1], x_vals[end], y_vals[1], y_vals[end]), cmap = "hot")
end
end
display(gcf())
# Calculate Laguerre_gaussian 0,0 to 3,3
for l in 0:3
for m in 0:3
Elm = zeros(Complex{Float64}, length(x_vals), length(y_vals))
for i in 1:length(x_vals)
for j in 1:length(y_vals)
Elm[i,j] = Laguerre_gaussian(x_vals[i], y_vals[j], 0, l, m)
end
end
# Plotting
subplot(4,4,l*4+m+1)
title("p is $l, m is $m")
imshow(abs2.(Elm), extent = (x_vals[1], x_vals[end], y_vals[1], y_vals[end]), cmap = "hot")
end
end
display(gcf())D4σの計算とその確認
# 積分関連のjulia 参考文献:https://zenn.dev/ohno/articles/440234fbb2adec#%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8
#using Pkg
#Pkg.add("QuadGK")
# calculation D4σ
using QuadGK
using SpecialPolynomials
using Polynomials
function Eₗₘ(x , y, z, l, m)
k = 1
z₀ = 0
ω₀ = 1
ϕ = atan(-(z-z₀)/(k*ω₀^2))
E₀ = 1
ω_z = ω₀/cos(ϕ)
Eₗₘ = (
E₀ * (ω₀/ω_z) * basis(Hermite, l)(√2*x/ω_z) * basis(Hermite, m)(√2*y/ω_z)
* exp(complex( -(x^2 + y^2)/(ω_z^2), -k*z+(l+m+1)*ϕ) )
)
return Eₗₘ
end
# D4σの計算 at julia my cord
function D4σ(z, l, m, x₀, y₀)
I(x, y) = abs2(Eₗₘ(x, y, l, m, z))
σ_x_numerator = quadgk(y ->
quadgk(x -> (x - x₀)^2 * I(x, y), -Inf, Inf; maxevals=10^3)[1],
-Inf, Inf; maxevals=10^3)[1]
σ_x_denominator = quadgk(y ->
quadgk(x -> I(x, y), -Inf, Inf; maxevals=10^3)[1],
-Inf, Inf; maxevals=10^3)[1]
σ_x = √( σ_x_numerator / σ_x_denominator )
σ_y_numerator = quadgk(x ->
quadgk(y -> (y - y₀)^2 * I(x, y), -Inf, Inf; maxevals=10^3)[1],
-Inf, Inf; maxevals=10^3)[1]
σ_y_denominator = quadgk(x->
quadgk(y -> I(x, y), -Inf, Inf; maxevals=10^3)[1],
-Inf, Inf; maxevals=10^3)[1]
σ_y = √( σ_y_numerator / σ_y_denominator )
return 2 * σ_x, 2 * σ_y
end
function e²_width(x_array,array_1d)
if length(x_array) != length(array_1d)
error("x_array and array_1d must have the same length")
end
max_value = maximum(array_1d)
threshold = max_value /exp(2)
indices = findall(x -> x > threshold, array_1d)
w = x_array[indices[end]] - x_array[indices[1]]
return w
end
ω_D4σ = D4σ(0, 0, 0, 0, 0) # l=0, m=0
print("ω_D4σ = ", ω_D4σ[1], "\n")
x_array = range(-3, 3, length=100)
E_lm = map(x -> Eₗₘ(x, 0, 0, 0, 0), x_array)
I = abs2.(E_lm)
w = e²_width(x_array,I)
print("w = ", w/2, "\n")M2の計算
using CSV
using DataFrames
# Base width
ωₓ_base, ωᵧ_base = D4σ_switch(0, 0, 0, 0, 0, "Hermite")
# 結果を格納するDataFrameを作成
results = DataFrame(Type = String[], l_or_p = Int[], m = Int[], M2_x = Float64[], M2_y = Float64[])
# Hermite-Gaussian
for l in 0:3
for m in 0:3
ωₓ, ωᵧ = D4σ_switch(0, l, m, 0, 0, "Hermite")
M2_x = (ωₓ / ωₓ_base)
M2_y = (ωᵧ / ωᵧ_base)
push!(results, ("Hermite", l, m, M2_x, M2_y))
end
end
# Laguerre-Gaussian
for p in 0:3
for m in 0:3
ωₓ, ωᵧ = D4σ_switch(0, p, m, 0, 0, "Laguerre")
M2_x = (ωₓ / ωₓ_base)
M2_y = (ωᵧ / ωᵧ_base)
push!(results, ("Laguerre", p, m, M2_x, M2_y))
end
end
# CSVファイルに保存
CSV.write("M2_parameters.csv", results)



コメント