ユーザ用ツール

サイト用ツール


tabuchi:xrayutils

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
tabuchi:xrayutils [2026/02/24 11:07] – [1.4 回折スペクトルの計算] mtabtabuchi:xrayutils [2026/02/27 17:27] (現在) – [1.2 構造因子の計算] mtab
行 5: 行 5:
  
 主な目的は 「1.使用例」 を示すことです。\\ 主な目的は 「1.使用例」 を示すことです。\\
-python の使用やプログラムを書くことについてはセミナーでは、より詳細な説明がありますのでそちらに従って下さい。+python の使用やプログラムを書くことについてはセミナーでは、より詳細な説明がありますのでそちらに従って下さい 
 +([[http://d2mate.mdxes.iir.isct.ac.jp/Lecture/jsap-crystal/seminar2025/|セミナーが推奨する神谷先生のwebページ]])
  
 後日、セミナーの受講とは別に xrayUtilities を試してみたいという時には「[[prepareXrayUtils|xrayUtilities の準備]]」を参照してみて下さい。 後日、セミナーの受講とは別に xrayUtilities を試してみたいという時には「[[prepareXrayUtils|xrayUtilities の準備]]」を参照してみて下さい。
行 175: 行 176:
 </code> </code>
 ++ ++
 +  - 構造因子のエネルギー依存性の計算と表示 ++ ここをクリックすると表示 |
 +<code python example-02-2.py>
 +#
 +# 構造因子の計算 (エネルギー依存)
 +#
 +
 +import xrayutilities as xu
 +import numpy
 +import matplotlib.pyplot as plt
 +
 +GaAs = xu.materials.GaAs
 +
 +energy= numpy.linspace(500, 20000, 5000) # 500 - 20000 eV
 +F = GaAs.StructureFactorForEnergy(GaAs.Q(1, 1, 1), energy)
 +
 +plt.figure(); plt.clf()
 +plt.plot(energy, F.real, '-k', label='Re(F)')
 +plt.plot(energy, F.imag, '-r', label='Imag(F)')
 +plt.xlabel("Energy (eV)"); plt.ylabel("F"); plt.legend()
 +
 +plt.show()
 +</code>
 +{{:tabuchi:ex-02-2.png?600|}}
 +++
 +
 +
 +
  
 ==== - 回折パタンの計算と逆格子マップの表示 ==== ==== - 回折パタンの計算と逆格子マップの表示 ====
行 198: 行 226:
 ++ ++
 ==== - 回折スペクトルの計算 ==== ==== - 回折スペクトルの計算 ====
-  - AlN/GaN(Sub)の回折スペクトルの計算と表示 ++ ここをクリックすると表示 |+  - AlN/GaN(Sub)の $\omega-2\theta$スペクトルの計算と表示 ++ ここをクリックすると表示 |
 <code python example-04-1.py> <code python example-04-1.py>
 # いつものおまじない。numpy, matplotlib, xrayutilities を使用可能にする # いつものおまじない。numpy, matplotlib, xrayutilities を使用可能にする
行 274: 行 302:
 {{:tabuchi:ex-04-1.png?600|}}\\ {{:tabuchi:ex-04-1.png?600|}}\\
 ++ ++
-  - AlGaN/GaN(Sub)の回折スペクトルの計算と表示 ++ ここをクリックすると表示 |+  - AlGaN/GaN(Sub)の$\omega-2\theta$スペクトルの計算と表示 ++ ここをクリックすると表示 |
 <code python example-04-2.py> <code python example-04-2.py>
 ##### プログラムはほとんど example-03-1.py と同じ ##### ##### プログラムはほとんど example-03-1.py と同じ #####
行 375: 行 403:
 緩和していないと、(GaNの方が格子定数が長くて、AlNの方が短いので、AlNは横方向に引っ張られて)AlNのc軸方向の面間隔が短くなるので $2d_{\rm c}\sin\theta = \lambda \Rightarrow \sin\theta = \lambda/2d_{\rm c}$ の関係から回折角 $\theta$ は大きくなるはずだが、実際そうなっていることがわかる。 緩和していないと、(GaNの方が格子定数が長くて、AlNの方が短いので、AlNは横方向に引っ張られて)AlNのc軸方向の面間隔が短くなるので $2d_{\rm c}\sin\theta = \lambda \Rightarrow \sin\theta = \lambda/2d_{\rm c}$ の関係から回折角 $\theta$ は大きくなるはずだが、実際そうなっていることがわかる。
 ++ ++
-  - 仮に生成したAlGaN/GaN(Sub)の回折スペクトルに対するなんちゃってフィッティング ++ ここをクリックすると表示 |+  - 仮に生成したAlGaN/GaN(Sub)の$\omega-2\theta$スペクトルに対するなんちゃってフィッティング ++ ここをクリックすると表示 |
 \\ この例では、真ん中あたりに出てくる \\ この例では、真ん中あたりに出てくる
   # この結果をフィッティング対象と考えて AlN 組成x と、緩和率 relaxation をパラメータとして   # この結果をフィッティング対象と考えて AlN 組成x と、緩和率 relaxation をパラメータとして
   # フィッティングをかけてみる   # フィッティングをかけてみる
 というコメント行までは、一つ前の例と同じコードです(一部変数名が違う)。\\ というコメント行までは、一つ前の例と同じコードです(一部変数名が違う)。\\
-ここでは、Al 組成 $x=0.2$、緩和の度合い $relaxation = 0.0$ で計算したスペクトルをまず計算し、これをフィッティング対象にしています。+ここでは、Al 組成 $x=0.2$、緩和の度合い $relaxation = 0.0$ でスペクトルをまず計算し、これをフィッティング対象にしています。
 このモデルに関連した変数は Target という名前が付いています。\\ このモデルに関連した変数は Target という名前が付いています。\\
 これに対して、Al組成と、緩和の度合いを未知パラメータとして RMC でフィッティングを試みています。\\ これに対して、Al組成と、緩和の度合いを未知パラメータとして RMC でフィッティングを試みています。\\
-「あってるか?」と試しに計算て受け入れられたもの(暫定的に合ってると判断されたもの)に関連する変数には Try_Now という名前が付いています。 +「あってるか?」と試しに計算て受け入れられたもの(暫定的に合ってると判断されたもの)に関連する変数には Try_Now という名前が付いています。 
-また別のパラメータで計算して、トライの値と優劣を比較す新しいものに関連する変数には Try_New という名前が付いています。\\+またTry_Now の値と優劣を比較する、別のパラメータやそれで計算されるものに関連する変数には Try_New という名前が付いています。\\
 実際に走らせると、グラフ表示の時点で止まります。グラフ表示のウインドウで 'q' を入力すると先に進みます。\\ 実際に走らせると、グラフ表示の時点で止まります。グラフ表示のウインドウで 'q' を入力すると先に進みます。\\
 残差が Limit (プログラム内で設定)より小さくなるか、パラメータが連続 5000回更新されなければ終了します。\\ 残差が Limit (プログラム内で設定)より小さくなるか、パラメータが連続 5000回更新されなければ終了します。\\
行 529: 行 557:
             RRange = Res / 10;             RRange = Res / 10;
         count = 0         count = 0
-        # 結果のプロット+        # 中間結果のプロット
         plt.figure()         plt.figure()
         plt.plot( twotheta/2, Int_Target )         plt.plot( twotheta/2, Int_Target )
行 553: 行 581:
 </code> </code>
 ++ ++
 +  - AlGaN/GaN(Sub)のロッキングカーブスペクトルの計算と表示 ++ ここをクリックすると表示 |
 +後半に出てくる、
 +  #### ここまでは先にやった omega-2theta のシミュレーションの時と同一 ####
 +と書かれた行までは、2つ目の例と同じコードです。
 +<code python example-04-4.py>
 +import numpy as np
 +import matplotlib.pyplot as plt
 +import xrayutilities as xu
  
 +# GaN, AlN の結晶構造をCIFから読む
 +GaN = xu.materials.Crystal.fromCIF("CIFs/GaN-Hex.cif")
 +AlN = xu.materials.Crystal.fromCIF("CIFs/AlN-Hex.cif")
 +
 +# 今作った結晶(GaN, AlN)は、結晶構造の情報しか持ってないので
 +# 積層構造にした時の歪の計算ができるように、弾性に関わる情報を追加する
 +#
 +## どちらも Hexagonal 
 +GaN.symm_class_name = 'Hexagonal'
 +AlN.symm_class_name = 'Hexagonal'
 +#
 +## GaN, AlN の弾性定数 Cij の値を、名前のついた値として準備
 +C11_GaN, C12_GaN, C13_GaN, C33_GaN, C44_GaN = 390, 145, 106, 398, 105
 +C11_AlN, C12_AlN, C13_AlN, C33_AlN, C44_AlN = 396, 137, 108, 373, 116
 +#
 +## xu にサポートしてもらって 2階テンソルの形に組み上げる
 +cij_array_GaN = xu.materials.material.HexagonalElasticTensor( C11_GaN, C12_GaN, C13_GaN, C33_GaN, C44_GaN )
 +cij_array_AlN = xu.materials.material.HexagonalElasticTensor( C11_AlN, C12_AlN, C13_AlN, C33_AlN, C44_AlN )
 +#
 +## さらに4階テンソルの形にもしておく ij to ijkl (プログラムでは '2' を 'to' の意味でよく使う)
 +cijkl_tensor_GaN = xu.materials.material.Cij2Cijkl(cij_array_GaN)
 +cijkl_tensor_AlN = xu.materials.material.Cij2Cijkl(cij_array_AlN)
 +#
 +## Crystal オブジェクト(GaN, AlN)に4階テンソルを属性として設定
 +setattr(GaN, 'cijkl', cijkl_tensor_GaN)
 +setattr(AlN, 'cijkl', cijkl_tensor_AlN)
 +#
 +## 2階テンソルも elastic 属性に代入
 +GaN.elastic = cij_array_GaN
 +AlN.elastic = cij_array_AlN
 +
 +# さらに混晶も準備する
 +Alx = 0.2                                                # Al組成 x = 0.2
 +AlGaN = xu.materials.material.Alloy(GaN, AlN, Alx);      # AlN 0.2 + GaN (1-0.2)
 +
 +# ここまでで、弾性定数の情報も持った GaN, AlN という結晶が準備できた。
 +# 次は、この物質のを積み上げていくためにその部品として Layer を作り、
 +# それを積み上げて積層構造にする
 +#
 +## まずは 基板(厚さ無限のGaN Layer)、AlN層を準備
 +sub    = xu.simpack.Layer( GaN, float('inf') )            # 基板 (GaN)
 +lGaN   = xu.simpack.Layer( GaN,   1500, relaxation=1.0 )  # 膜 (GaN)       # ここでは使わない
 +lAlN   = xu.simpack.Layer( AlN,   1500, relaxation=1.0 )  # 膜 (AlN)       # ここでは使わない
 +lAlGaN = xu.simpack.Layer( AlGaN, 1500, relaxation=0.0 )  # 膜 (Al0.2GaN)  # relaxation=1.0 => 0.0 にすると回折ピークは広角側に動く
 +#
 +## 準備した Layer を積み上げて AlN層 / GaN 基板という積層構造を構築
 +Epi_Sub = xu.simpack.PseudomorphicStack001( "AlN/GaN", sub+lAlGaN )
 +
 +# ω-2θ 強度計算
 +## 波長、エネルギー、計算する角度範囲指定
 +wavelength = xu.wavelength('CuKa1'          # 波長は Cu Ka1 の波長(1.5405...A)
 +energy     = 12390 / wavelength               # エネルギーは波長から計算
 +two_theta  = np.linspace( 32, 38, 200 )       # 横軸になる角度範囲のベクトルを作っておく
 +
 +#### ここまでは先にやった omega-2theta のシミュレーションの時と同一 ####
 +
 +# 動的モデルの設定とシミュレーション
 +## リファレンスに基板(GaN)だけの計算もする
 +sub_model         = xu.simpack.DynamicalModel( sub,     energy=energy, resolution_width=0.0001 )
 +int_w2th_sub      = sub_model.simulate( two_theta/2, hkl=(0, 0, 2) )  # 基板だけの時の omega-2theta スペクトル
 +peak_index_sub    = np.argmax( int_w2th_sub )                         # そのピーク位置(2theta)の指数
 +peak_sub          = two_theta[ peak_index_sub ]                       # そのピーク位置(2theta)の角度
 +omega_sub         = np.linspace( peak_sub/2-0.5, peak_sub/2+0.5, 400 )  # 今わかった角度+/-0.5 omega の範囲を対称に
 +int_RC_sub        = sub_model.simulate( omega_sub, hkl=(0,0,2), geometry="omega" ) # ロッキングカーブ方向の強度計算
 +
 +## こちらは Epi/Sub = AlGaN/GaN の計算
 +epi_sub_model      = xu.simpack.DynamicalModel( Epi_Sub, energy=energy, resolution_width=0.0001 )
 +int_w2th_epi_sub   = epi_sub_model.simulate( two_theta/2, hkl=(0, 0, 2) ) # omega-2theta スペクトル
 +peak_index_epi_sub = np.argmax( int_w2th_epi_sub )                        # そのピーク index
 +peak_epi_sub       = two_theta[ peak_index_epi_sub ]                      # ピーク角度
 +omega_epi_sub      = np.linspace( peak_epi_sub/2-0.5, peak_epi_sub/2+0.5, 400 )
 +int_RC_epi_sub     = epi_sub_model.simulate( omega_epi_sub, hkl=(0,0,2), geometry="omega" )
 +
 +# 結果のプロット
 +plt.figure()
 +plt.plot( omega_sub     - peak_sub/2,     int_RC_sub )
 +plt.plot( omega_epi_sub - peak_epi_sub/2, int_RC_epi_sub )
 +plt.title( 'Dynamical Simulation of Rocking Curve of AlGaN/GaN and GaN Sub')
 +plt.yscale('log')
 +plt.xlabel(r'$\omega\ (deg)$')
 +plt.ylabel('Intensity (arb. u.)')
 +plt.show()
 +</code>
 +{{:tabuchi:ex-04-4.png?600|}}\\
 +青線が基板(GaN)のロッキングカーブで、オレンジ線がAlGaN/GaNのロッキングカーブ。
 +2シータはそれぞれについてシミュレーションで計算された $\omega-2\theta$ スペクトルのピーク位置に合わせて計算されてます
 +(単純に「一番値が大きいところ」なので、AlGaN/GaN も基板のピークを捕まえてるかも)。
 +いずれにしても、AlGaN/GaN のロッキングカーブは、基板(GaN)のスペクトルを含んでしまってます。
 +これは、$2\theta$を制限しない計算になっているためで、現実の測定で言うと、検出器前スリットを前回にして測定している状況に相当します。
 +現実でも、この様な設定で測定を行うとロッキングカーブを見ているのか$\omega-2\theta$を見ているのかよくわからなくなりますが、
 +この計算はそれを再現していることになります。
 +++
 ------ ------
 [[講演資料|田渕の講演資料の一部]]\\ [[講演資料|田渕の講演資料の一部]]\\
tabuchi/xrayutils.1771931243.txt.gz · 最終更新: by mtab