MateriApps
物質科学シミュレーションのポータルサイト

現在アプリ掲載数332件

お問合せ / アプリ掲載依頼
    • JP
    • EN
  • MateriApps について
  • レビュー募集
もっと詳しく探す
  • NEWS / 講習会・イベント
  • アプリ一覧
  • アプリ詳細検索
  • キーワード解説
  • レビュー
  • 事例
  • アプリコンシェルジュ
  • インストールしないでアプリを
    試せる「MateriApps LIVE!」

    詳細はこちら
  • MateriApps について
  • レビュー募集
  • プライバシーポリシー
  • お問合せ / アプリ掲載依頼
  • アプリ一覧
  • QUANTUM ESPRESSO
QE logo

QUANTUM ESPRESSO

  • 公開度:3 ★★★
  • ドキュメント充実度:3 ★★★

擬ポテンシャル法と平面波基底を用いた第一原理計算ライブラリ。広範な物理系に対して、密度汎関数法に基づく電子状態計算を高精度で行うことができる。基本プログラムのほかに多数のコアパッケージ・プラグインが含まれ、無償ながら研究・開発に利用できる多くの充実した機能を持つ。MPIによる並列計算にも対応している。

Quantum ESPRESSOのNiOの結果を可視化する
Last Update:2025/10/28
あなたはすでに投票済みです!

MateriApps開発チーム

NiOの反強磁性の計算を行う。

下記のpw.xの入力ファイルNiO.inを作成する。

&CONTROL
  calculation = 'scf'
  etot_conv_thr =   4.0000000000d-05
  forc_conv_thr =   1.0000000000d-04
  outdir = './out/'
  prefix        = 'nio'
  pseudo_dir = './'
  tprnfor = .true.
  tstress = .true.
/

&SYSTEM
  degauss =   2.0000000000d-02
  ecutrho =   4.0000000000d+02
  ecutwfc =   5.0000000000d+01
  ibrav = 0
  nat = 4
  nosym = .false.
  nspin = 2
  ntyp = 3
  occupations = 'smearing'
  smearing = 'cold'
  starting_magnetization(1) = 5.0
  starting_magnetization(2) = -5.0
  starting_magnetization(3) = 0.0
  tot_magnetization = 0.0
/

&ELECTRONS
  conv_thr =   8.0000000000d-10
  electron_maxstep = 80
  mixing_beta =   4.0000000000d-01
/

ATOMIC_SPECIES
Ni1     58.6934 ni_pbesol_v1.4.uspp.F.UPF
Ni2     58.6934 ni_pbesol_v1.4.uspp.F.UPF
O      15.9994 O.pbesol-n-kjpaw_psl.0.1.UPF

ATOMIC_POSITIONS crystal
Ni1           0.0000000000       0.0000000000       0.0000000000
Ni2           0.5000000000       0.5000000000       0.5000000000
O            0.2500010000       0.7499990000       0.2499930000
O            0.7499990000       0.2500010000       0.7500070000

K_POINTS automatic
17 17 9 0 0 0

CELL_PARAMETERS angstrom
      2.9830770400       0.0000000000       0.0000000000
     -1.4914536616       2.5834751934       0.0000000000
      1.4915830092      -0.8611884515       4.8640030001

HUBBARD (ortho-atomic)
   U Ni1-3d 6.0
   U Ni2-3d 6.0

次に擬ポテンシャルをダウンロードしたのち、pw.xを実行する。

$ wget https://www.physics.rutgers.edu/gbrv/ni_pbesol_v1.4.uspp.F.UPF
$ wget https://pseudopotentials.quantum-espresso.org/upf_files/O.pbesol-n-kjpaw_psl.0.1.UPF
$ pw.x < NiO.in > NiO.out

可視化には、実行結果NiO.outを用いる。

# plot_spin.py
import matplotlib
matplotlib.use('Agg')

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

# --- 設定項目 ---
# Quantum ESPRESSOの出力ファイルへのパスを指定してください
QE_OUTPUT_FILE = 'NiO.out'
OUTPUT_IMAGE_FILE = 'spin_structure.png' # 保存する画像ファイル名

# 描画設定
SPIN_SCALE_FACTOR = 1.8  # スピンの矢印の長さを調整する係数
ATOM_SIZE = 200          # 原子を表す点の大きさ
SPIN_THRESHOLD = 0.1     # この値(Bohr mag)以下の磁化を持つ原子のスピンは表示しない

# 元素ごとの色を定義 (計算に合わせて追加・変更してください)
ELEMENT_COLORS = {
    'Ni': 'darkcyan',
    'O': 'red',
}

# --- Quantum ESPRESSO出力解析 ---

def parse_qe_output(filepath):
    """
    Quantum ESPRESSO (pw.x) のSCF出力ファイルをパースする。
    最後の構造と磁化の情報を抽出する。
    """
    BOHR_TO_ANGSTROM = 0.529177210903
    alat, lattice_vectors_alat, atoms, magnetization = None, [], [], []

    try:
        with open(filepath, 'r') as f:
            lines = f.readlines()
    except FileNotFoundError:
        raise FileNotFoundError(f"エラー: ファイル '{filepath}' が見つかりません。")

    # 構造情報を抽出
    alat_line = next((line for line in lines if 'lattice parameter (alat)' in line), None)
    if alat_line:
        alat_bohr = float(alat_line.split('=')[1].split()[0])
        alat = alat_bohr * BOHR_TO_ANGSTROM

    axes_start_index = next((i for i, line in enumerate(lines) if 'crystal axes: (cart. coord. in units of alat)' in line), None)
    if axes_start_index is not None:
        for i in range(1, 4):
            line = lines[axes_start_index + i]
            vec_part = line.split('=')[1]
            vec_str = vec_part.replace('(', '').replace(')', '').strip()
            vec = [float(x) for x in vec_str.split()]
            lattice_vectors_alat.append(vec)

    pos_start_index = next((i for i, line in enumerate(lines) if 'site n.     atom                  positions (alat units)' in line), None)
    if pos_start_index is not None:
        for i in range(pos_start_index + 1, len(lines)):
            line = lines[i]
            if 'tau(' in line:
                parts = line.split()
                element = ''.join(filter(str.isalpha, parts[1]))
                coord_part = line.split('=')[1]
                coords_str = coord_part.replace('(', '').replace(')', '').strip()
                coords_alat = np.array([float(c) for c in coords_str.split()])
                atoms.append({'element': element, 'coords_alat': coords_alat})
            elif not line.strip():
                break

    mag_start_index = -1
    for i in range(len(lines) - 1, -1, -1): # 後ろからインデックスを探索
        if 'Magnetic moment per site' in lines[i]:
            mag_start_index = i
            break # 最初に見つかった(=ファイルの一番後ろの)セクションで確定
            
    # 見つかった場合、そのセクションを読み込む
    if mag_start_index != -1:
        for i in range(mag_start_index + 1, len(lines)):
            line = lines[i]
            if 'atom' in line and 'magn=' in line:
                magn_z = float(line.split('magn=')[1].split()[0])
                magnetization.append(magn_z)
            # 磁化セクションの終わりを判定 (空行または別のセクションの開始)
            elif not line.strip() or 'total cpu time' in line:
                break # 磁化セクション後の空行などでループを抜ける

    # --- データ検証と整形 ---
    if not all([alat, lattice_vectors_alat, atoms, magnetization]):
        # デバッグ用にどの情報が欠けているかを表示
        print("--- デバッグ情報 ---")
        print(f"格子定数 (alat) 抽出成功: {'はい' if alat else 'いいえ'}")
        print(f"格子ベクトル (lattice_vectors_alat) 抽出成功: {'はい' if lattice_vectors_alat else 'いいえ'}")
        print(f"原子座標 (atoms) 抽出成功: {'はい' if atoms else 'いいえ'}")
        print(f"磁化 (magnetization) 抽出成功: {'はい' if magnetization else 'いいえ'}")
        print("--------------------")
        raise ValueError("エラー: 出力ファイルから必要な情報(格子、原子、磁化)をすべて抽出できませんでした。")

    if len(atoms) != len(magnetization):
        raise ValueError(f"エラー: 原子数({len(atoms)})と磁化の数({len(magnetization)})が一致しません。")

    lattice_vectors = np.array(lattice_vectors_alat) * alat
    final_atoms = [{'element': atom['element'], 'coords': atom['coords_alat'] * alat} for atom in atoms]
    spin_vectors = [[0.0, 0.0, mz] for mz in magnetization]

    return {
        'lattice_vectors': lattice_vectors,
        'atoms': final_atoms,
        'spin_vectors': spin_vectors,
    }

# --- メインの描画処理 (変更なし) ---
def plot_spin_structure_from_qe(qe_outfile):
    try:
        data = parse_qe_output(qe_outfile)
    except (ValueError, FileNotFoundError) as e:
        print(e)
        return

    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')

    for i, atom in enumerate(data['atoms']):
        x, y, z = atom['coords']
        element = atom['element']
        color = ELEMENT_COLORS.get(element, 'gray')
        ax.scatter([x], [y], [z], s=ATOM_SIZE, c=color, label=element, depthshade=False)
        
        mx, my, mz = data['spin_vectors'][i]
        if np.linalg.norm([mx, my, mz]) > SPIN_THRESHOLD:
            ax.quiver(x, y, z, mx, my, mz,
                      length=SPIN_SCALE_FACTOR,
                      normalize=True,
                      color='black',
                      arrow_length_ratio=0.3)

    vectors = data['lattice_vectors']
    origin = np.array([0,0,0])
    corners = [
        origin, origin + vectors[0], origin + vectors[1], origin + vectors[2],
        origin + vectors[0] + vectors[1], origin + vectors[0] + vectors[2],
        origin + vectors[1] + vectors[2], origin + vectors[0] + vectors[1] + vectors[2]
    ]
    edges = [
        (0, 1), (0, 2), (0, 3), (1, 4), (1, 5), (2, 4),
        (2, 6), (3, 5), (3, 6), (4, 7), (5, 7), (6, 7)
    ]
    for start_idx, end_idx in edges:
        p1, p2 = corners[start_idx], corners[end_idx]
        ax.plot3D(*zip(p1, p2), color="gray", linestyle='--')
    
    ax.set_xlabel('X (Å)')
    ax.set_ylabel('Y (Å)')
    ax.set_zlabel('Z (Å)')
    ax.set_title('Crystal Structure with Spin Vectors (from Quantum ESPRESSO)')
    
    handles, labels = ax.get_legend_handles_labels()
    by_label = dict(zip(labels, handles))
    ax.legend(by_label.values(), by_label.keys())

    x_lims, y_lims, z_lims = ax.get_xlim(), ax.get_ylim(), ax.get_zlim()
    ax.set_box_aspect([lim[1] - lim[0] for lim in [x_lims, y_lims, z_lims]])
    ax.set_anchor('C')

    plt.savefig(OUTPUT_IMAGE_FILE, dpi=300, bbox_inches='tight')
    print(f"画像 '{OUTPUT_IMAGE_FILE}' を保存しました。")
    plt.show()


if __name__ == '__main__':
    plot_spin_structure_from_qe(QE_OUTPUT_FILE)

上記のpythonスクリプト plot_spin.pyを作成し、

pythoh3 plot_spin.py

を実行すると下記の図のspin_structure.pngが作成される。

04 / 06

  • 01基本情報
  • 02事例・論文
  • 03講習会
  • 04レビュー
  • 05開発者の声
  • 06このアプリ情報に
    ついてのお問い合わせ
TOP

MateriApps
物質科学シミュレーションのポータルサイト

  • NEWS / 講習会・イベント
  • アプリ一覧
  • アプリ詳細検索
  • キーワード解説
  • 事例
  • アプリコンシェルジュ
  • プライバシーポリシー
お問合せ / アプリ掲載依頼
  • 東京大学 物性研究所 The Institute for Solid State Physics
  • 東京大学 The University of Tokyo
  • CDMSI
  • CCMS

© MateriApps, 2013-2025. All rights reserved.