crystal.atominf_xrayutilities のソースコード

"""
X線反射率測定 (XRR) シミュレーションを行うためのスクリプト。

xrayutilities と pymatgen を使用して多層膜サンプルのXRRプロファイルを計算し、プロットします。
CIFファイルからの構造読み込みにも対応しています。

:doc:`atominf_xrayutilities_usage`
"""
# pip install xrayutilities pymatgen matplotlib numpy

import os
import numpy as np
import matplotlib.pyplot as plt
import xrayutilities as xu
from pymatgen.core import Composition, Structure


# ====== 単位変換 ======
[ドキュメント] def gcm3_to_kgm3(rho): """ 密度をg/cm³からkg/m³に変換します。 :param rho: 密度 (g/cm³)。 :type rho: float or int :returns: 密度 (kg/m³)。 :rtype: float """ return float(rho) * 1000.0
[ドキュメント] def nm_to_A(t_nm): """ 厚さをナノメートル(nm)からオングストローム(A)に変換します。 :param t_nm: 厚さ (nm)。 :type t_nm: float or int :returns: 厚さ (A)。 :rtype: float """ return float(t_nm) * 10.0
[ドキュメント] def is_cif_path(s): """ 与えられた文字列がCIFファイルのパスであるかを判定します。 文字列が `str` 型であり、`.cif` で終わる場合にTrueを返します(大文字・小文字を区別しない)。 :param s: 判定する文字列。 :type s: str :returns: CIFファイルパスであればTrue、そうでなければFalse。 :rtype: bool """ return isinstance(s, str) and s.lower().endswith(".cif")
[ドキュメント] def load_from_cif(path): """ 指定されたCIFファイルから構造、化学式、密度を読み込みます。 `pymatgen` を使用してCIFファイルを解析し、`Structure`オブジェクト、 還元化学式、および密度 (g/cm³) を抽出します。 :param path: CIFファイルへのパス。 :type path: str :returns: - `structure` (`pymatgen.core.Structure`): 読み込まれた結晶構造オブジェクト。 - `formula` (str): 構造の還元化学式。 - `density` (float): 構造の密度 (g/cm³)。 :rtype: tuple[pymatgen.core.Structure, str, float] """ structure = Structure.from_file(path) formula = structure.composition.reduced_formula density = float(structure.density) return structure, formula, density
[ドキュメント] def main(): """ 多層膜のXRRシミュレーションを実行し、結果をプロットします。 層構造と基板の情報を定義し、それらから `xrayutilities` の `LayerStack` オブジェクトを構築します。 その後、XRRモデルを使用して反射率プロファイルを計算し、`matplotlib` で表示します。 CIFファイルからの層情報の読み込みもサポートしています。 """ # ====== 層構造 ====== layer_stack = [ {"composition": "TiO2", "density_gcm3": 4.23, "thickness_nm": 50.0, "roughness_A": 0.5}, {"composition": "Al2O3", "density_gcm3": 3.95, "thickness_nm": 30.0, "roughness_A": 0.5}, {"composition": "SiO2", "density_gcm3": 2.20, "thickness_nm": 100.0, "roughness_A": 0.5}, # {"composition": "sample.cif", "density_gcm3": 0.0, "thickness_nm": 10.0, "roughness_A": 0.5}, ] substrate = {"composition": "Si", "density_gcm3": 2.33, "roughness_A": 0.5} # ====== 表示:分子量 ====== print("各層の化学組成と分子量:") for layer in layer_stack: comp = layer["composition"] if is_cif_path(comp): _, formula, _ = load_from_cif(comp) mw = Composition(formula).weight print(f" {os.path.basename(comp)} ({formula}): {mw:.3f} g/mol") else: mw = Composition(comp).weight print(f" {comp}: {mw:.3f} g/mol") # ====== 基板 ====== sub_mat = xu.materials.Amorphous(substrate["composition"], gcm3_to_kgm3(substrate["density_gcm3"])) stack = xu.simpack.Layer(sub_mat, float("inf"), roughness=substrate["roughness_A"]) # ====== 薄膜層 ====== for layer in layer_stack: comp = layer["composition"] rho = float(layer["density_gcm3"]) if is_cif_path(comp): _, formula, rho_cif = load_from_cif(comp) if rho <= 0.0: rho = rho_cif comp = formula mat = xu.materials.Amorphous(comp, gcm3_to_kgm3(rho)) lay = xu.simpack.Layer(mat, nm_to_A(layer["thickness_nm"]), roughness=layer["roughness_A"]) stack = stack + lay sample = xu.simpack.LayerStack("sample", stack) # ====== XRR ====== model = xu.simpack.SpecularReflectivityModel(sample, energy="CuKa1") alphai = np.linspace(0.05, 2.5, 2000) R = model.simulate(alphai) two_theta = 2 * alphai plt.figure(figsize=(8, 5)) plt.semilogy(two_theta, R) plt.xlabel("2θ (deg)") plt.ylabel("Reflectivity") plt.title("Multilayer XRR Simulation") plt.grid(True, which="both") plt.tight_layout() plt.show()
if __name__ == "__main__": main()