crystal.bond_valence_sum_BVAnalyzer のソースコード

"""
概要: CIFファイルから構造を読み込み、pymatgenのBVAnalyzerを用いて結合価数和 (BVS) を計算し表示するスクリプト。

詳細説明:
このスクリプトは、指定されたCIFファイルから結晶構造を解析し、各原子サイトにおける結合価数和を計算します。
主にpymatgenライブラリのBVAnalyzerおよびcalculate_bv_sum関数を利用しています。
計算には、N. E. Brese & M. O’KeeffeによるBond-valence parameters for solids (Acta Crystallographica Section B, 1991, 47(2), 192–197, DOI: 10.1107/S0108768190011041)
に基づくパラメータセットを使用しています。これらのパラメータはB=0.31を固定値として、元素ごとにrとcを定めています。
パラメータファイルは通常、pymatgenのインストールディレクトリ内のbvparam_1991.yamlにあります。
スクリプトは、BVAnalyzerの各種設定(最大半径など)を表示し、calculate_bv_sumを用いた直接計算と、
BVAnalyzerによる価数割り当てを試行し、その結果を出力します。

関連リンク:
:doc:`bond_valence_sum_BVAnalyzer_usage`
"""
import os
import sys
import argparse
import pprint

from pymatgen.core.structure import Structure
from pymatgen.analysis.bond_valence import BVAnalyzer
from pymatgen.analysis.bond_valence import calculate_bv_sum
import pymatgen.analysis.bond_valence as bv_mod


# BVAnalyzer
#著者:N. E. Brese & M. O’Keeffe
#タイトル:Bond-valence parameters for solids
#雑誌:Acta Crystallographica Section B: Structural Science, Crystal Engineering and Materials
#巻 (Volume):47
#号 (Issue):2
#ページ:192–197
#発行年:1991年(April 1991)
#DOI:10.1107/S0108768190011041
# O’Keefe & Brese の文献に基づくパラメータセット(元素ごとにr,cを決め, B=0.31)を使用
# C:\Users\tkami\AppData\Local\Programs\Python\Python312\Lib\site-packages\pymatgen\analysis\bvparam_1991.yaml
# 例: Zn,Oのr,c から、r0を計算
# r0 = r_zn + r_o - (r_zn * r_o * (sqrt(c_zn) - sqrt(c_o))**2) / (c_zn * r_zn + c_o * r_o)


[ドキュメント] def main(): """ 概要: コマンドライン引数に基づいてCIFファイルから結合価数和を計算し、結果を表示するメイン関数。 詳細説明: この関数は、コマンドライン引数としてCIFファイルのパスと最大近接距離を受け取ります。 指定されたCIFファイルが存在しない場合はエラーメッセージを表示して終了します。 ファイルが読み込まれると、pymatgenのStructureオブジェクトが作成され、 BVAnalyzerが指定された最大近接距離で初期化されます。 BVAnalyzerの設定、使用されるパラメータファイルの情報、およびZn-O結合のパラメータ例を表示します。 その後、Structure内の各サイトについて、指定された最大近接距離内の最近接原子のリストを取得し、 calculate_bv_sum関数を用いて結合価数和を計算し出力します。 さらに、異なるカットオフ半径でのcalculate_bv_sumの振る舞いを試行し、結果を表示します。 最後に、BVAnalyzerのget_valencesメソッドを使用して各サイトの結合価数和を計算し、表示します。 エラー発生時には、結合価数和の計算をスキップし、メッセージを表示して継続します。 :param: なし (コマンドライン引数 `cif_file` と `max_r` を使用) :returns: None """ parser = argparse.ArgumentParser( description="Calculate Bond Valence Sums from a CIF file using pymatgen" ) parser.add_argument("cif_file", help="Path to the CIF file") parser.add_argument("--max_r", type=float, default=2.8, help="Maximum neighbor distance for BVAnalyzer (Å)") args = parser.parse_args() if not os.path.isfile(args.cif_file): print(f"Error: CIF file not found: {args.cif_file}") sys.exit(1) structure = Structure.from_file(args.cif_file) bva = BVAnalyzer(max_radius=args.max_r) print() print(f"cif_file: {args.cif_file}") print(f"max_r: {args.max_r}") print() print("=== BVAnalyzer settings ===") print(f"symm_tol = {bva.symm_tol}") print(f"max_radius = {bva.max_radius}") print(f"distance_scale_factor = {bva.dist_scale_factor}") print(f"max_permutations = {bva.max_permutations}") print(f"charge_neutrality_tol = {bva.charge_neutrality_tolerance}") # print(f"forbidden_species = {bva.forbidden_species}") param_dir = os.path.dirname(bv_mod.__file__) param_file = os.path.join(param_dir, "bvparam_1991.yaml") print("\n=== Default parameter file ===") print(param_file) print("\n=== Example: Zn–O parameters ===") # BV_PARAMS は {element: {neighbor: {"r":…, "c":…}, …}, …} pprint.pprint(bv_mod.BV_PARAMS.get("Zn", {}).get("O")) print() print("Calculate BVS:") for site in structure.sites: nn = structure.get_neighbors(site, args.max_r) bvs = calculate_bv_sum(site, nn, scale_factor=bva.dist_scale_factor) print(f"site {site.specie.symbol} nn_count={len(nn)} BVS={bvs:.3f}") print() print("\n=== calculate_bv_sum で距離を変えてみる ===") for rcut in [0.0, 1.5, 2.0, 2.5, 3.0]: bva = BVAnalyzer(max_radius=rcut) try: structure = bva.get_oxi_state_decorated_structure(structure) except: # get_oxi_state_decorated_structure が失敗した場合、それ以降のBVS計算をスキップしてループを抜ける print(f"Warning: Failed to decorate structure with oxidation states for rcut={rcut} Å.") print("Skipping further BVAnalyzer calculations for varying rcut.") break # 各サイトごとに nearest neighbors を取り、BVS を直接計算 for site in structure.sites: nn = structure.get_neighbors(site, rcut) bvs = calculate_bv_sum(site, nn, scale_factor=bva.dist_scale_factor) print(f"rcut={rcut:3.1f} Å, site={site.specie.symbol}, nn={len(nn)}, BVS={bvs:.3f}") print("-" * 40) print("BVAnalyzer result:") try: valences = bva.get_valences(structure) except Exception as e: print(f"Error: Failed to get valences from BVAnalyzer. {e}") valences = None if valences: for i, (site, bv_sum) in enumerate(zip(structure.sites, valences)): symbol = site.specie.symbol coords = site.frac_coords print(f"{i:2d}: {symbol:2s} at {coords} → BVS = {bv_sum:.3f}") input("\nPress ENTER to terminate>>\n")
if __name__ == "__main__": main()