tklib.tkcrystal.tkboltztrap のソースコード

"""
tkboltztrapモジュール

BoltzTraP計算の入出力ファイルを操作するためのクラスとユーティリティを提供します。
BoltzTraPは、半古典的Boltzmann輸送方程式に基づいて、電子構造計算(VASPなど)から
輸送特性(電気伝導度、ゼーベック係数、熱伝導度など)を計算するプログラムです。

関連リンク: :doc:`tkboltztrap_usage`
"""
import os
import sys
import shutil
import copy
import glob
import re
import csv
import numpy as np
from numpy import sin, cos, tan, arccos, arcsin, arctan, sqrt, exp, log, pi
from pprint import pprint

from tklib.tkobject import tkObject
from tklib.tkutils import IsDir, IsFile, SplitFilePath, pconv, pint, pfloat, safe_getelement
from tklib.tkutils import terminate, pint, pfloat, getarg, getintarg, getfloatarg
from tklib.tkutils import SplitFilePath, GetList
from tklib.tkre    import DelQuote, DelSpace
import tklib.tkre
from tklib.tkfile import tkFile
from tklib.tkcrystal.tkcrystalobject import tkCrystalObject
from tklib.tkcrystal.tkspacegroup import tkSpaceGroup
from tklib.tkprogvars import ProgramDir, DBDir, AtomDBDir, VASPDir, VASPPerlDir, VASPPythonDir
from tklib.tkfile import tkFile
from tklib.tkinifile import tkIniFile
from tklib.tksci.tksci import Reduce01, Round
from tklib.tksci.tksci import pi, torad, todeg, Round, Factorize, IsFactor
from tklib.tksci.tksci import a0, NA, h, hbar, e, c, e0, kB, me, RyToeV, HartreeToeV, JToeV, eVToJ
from tklib.tksci.tksci import degcos, degsin, degtan, acos,asin, atan, degacos, degasin, degatan
from tklib.tksci.tkintegration import rieman_array_func
from tklib.tksci.tkmatrix import make_matrix1, make_matrix2, make_matrix3
from tklib.tkcrystal.tkcrystal import tkCrystal
from tklib.tktransport.tkTransport import fe, fh


[ドキュメント] class tkBoltzTraP(tkCrystalObject): """ BoltzTraP計算に関連するデータと操作を管理するクラス。 このクラスは、BoltzTraPの入力ファイル、出力ファイル、およびVASPの関連ファイル (INCAR, OUTCAR, EIGENVAL, DOSCARなど)のパス管理、読み込み、データ抽出機能を提供します。 tkCrystalObjectを継承しており、結晶構造に関連する情報も扱えます。 """ def __init__(self, **args): """ tkBoltzTraPオブジェクトを初期化します。 :param args: キーワード引数として属性の初期値を設定します。 :type args: dict """ self.workdir = None self.crystal = None self.incarinf = None self.kpointsinf = None self.outcarinf = None self.eigenvalinf = None self.update(**args) def __del__(self): """ tkBoltzTraPオブジェクトのデストラクタです。 特にクリーンアップ処理は行いません。 """ pass def __str__(self): """ オブジェクトの文字列表現を返します。 このメソッドは、`ClassPath` メソッドの結果を返します。 :returns: オブジェクトのクラスパスを示す文字列。 :rtype: str """ return self.ClassPath() def __del__(self): """ tkBoltzTraPオブジェクトのデストラクタです。 特にクリーンアップ処理は行いません。 """ pass
[ドキュメント] def get_path(self, filebody, dir = None): """ 指定されたファイルボディとディレクトリに基づいて完全なファイルパスを生成します。 ディレクトリが指定されていない場合、オブジェクトの `workdir` 属性を使用します。 :param filebody: ファイル名またはファイルボディ。 :type filebody: str :param dir: ファイルが存在するディレクトリのパス。Noneの場合、`self.workdir` を使用します。 :type dir: str or None :returns: 完全なファイルパス。 :rtype: str """ if dir is None: dir = self.workdir else: self.workdir = dir return os.path.join(dir, filebody)
[ドキュメント] def get_intranspath(self, filebody, dir = None): """ BoltzTraPの入力ファイル (intrans) の完全なファイルパスを生成します。 ファイルボディに `.intrans` 拡張子を付加します。 :param filebody: intransファイルのボディ(拡張子なし)。 :type filebody: str :param dir: ファイルが存在するディレクトリのパス。Noneの場合、`self.workdir` を使用します。 :type dir: str or None :returns: intransファイルの完全なパス。 :rtype: str """ return self.get_path(f'{filebody}.intrans', dir)
[ドキュメント] def get_outputtranspath(self, filebody, dir = None): """ BoltzTraPの出力サマリーファイル (outputtrans) の完全なファイルパスを生成します。 ファイルボディに `.outputtrans` 拡張子を付加します。 :param filebody: outputtransファイルのボディ(拡張子なし)。 :type filebody: str :param dir: ファイルが存在するディレクトリのパス。Noneの場合、`self.workdir` を使用します。 :type dir: str or None :returns: outputtransファイルの完全なパス。 :rtype: str """ return self.get_path(f'{filebody}.outputtrans', dir)
[ドキュメント] def get_transdospath(self, filebody, dir = None): """ BoltzTraPの輸送DOSファイル (transdos) の完全なファイルパスを生成します。 ファイルボディに `.transdos` 拡張子を付加します。 :param filebody: transdosファイルのボディ(拡張子なし)。 :type filebody: str :param dir: ファイルが存在するディレクトリのパス。Noneの場合、`self.workdir` を使用します。 :type dir: str or None :returns: transdosファイルの完全なパス。 :rtype: str """ return self.get_path(f'{filebody}.transdos', dir)
[ドキュメント] def get_tracepath(self, filebody, dir = None): """ BoltzTraPのDOS補間ファイル (trace) の完全なファイルパスを生成します。 ファイルボディに `.trace` 拡張子を付加します。 :param filebody: traceファイルのボディ(拡張子なし)。 :type filebody: str :param dir: ファイルが存在するディレクトリのパス。Noneの場合、`self.workdir` を使用します。 :type dir: str or None :returns: traceファイルの完全なパス。 :rtype: str """ return self.get_path(f'{filebody}.trace', dir)
# return self.get_path('interpolation.trace', dir)
[ドキュメント] def get_condtenspath(self, filebody, dir = None): """ BoltzTraPの輸送テンソルファイル (condtens) の完全なファイルパスを生成します。 ファイルボディに `.condtens` 拡張子を付加します。 :param filebody: condtensファイルのボディ(拡張子なし)。 :type filebody: str :param dir: ファイルが存在するディレクトリのパス。Noneの場合、`self.workdir` を使用します。 :type dir: str or None :returns: condtensファイルの完全なパス。 :rtype: str """ return self.get_path(f'{filebody}.condtens', dir)
# return self.get_path('interpolation.condtens', dir)
[ドキュメント] def get_halltenspath(self, filebody, dir = None): """ BoltzTraPのホールテンソルファイル (halltens) の完全なファイルパスを生成します。 ファイルボディに `.halltens` 拡張子を付加します。 :param filebody: halltensファイルのボディ(拡張子なし)。 :type filebody: str :param dir: ファイルが存在するディレクトリのパス。Noneの場合、`self.workdir` を使用します。 :type dir: str or None :returns: halltensファイルの完全なパス。 :rtype: str """ return self.get_path(f'{filebody}.halltens', dir)
# return self.get_path('interpolation.halltens', dir)
[ドキュメント] def get_labels(self, latex_style = 0): """ BoltzTraPの出力データ(condtensなど)の列ラベルを取得します。 電気伝導度、ゼーベック係数、熱伝導度に関するラベルが含まれます。 :param latex_style: ラベルをLaTeX形式にするかどうか。0の場合はプレーンテキスト。 :type latex_style: int :returns: ラベルのリスト。 :rtype: list of str """ if latex_style: return ['EF[Ry]', 'T[K]', 'N[e/uc]', '$\\sigma_{xx}/\\tau_0$[1/(ohm*m*s)]', 'sigma_xy', 'signma_xz', 'signma_yx', 'signma_yy', 'signma_yz', 'signma_zx', 'signma_zy', 'signma_zz', '$S_{xx}$[V/K]', '$S_{xy}$', '$S_{xz}$', '$S_{yx}$', '$S_{yy}$', '$S_{yz}$', '$S_{zx}$', '$S_{zy}$', '$S_{zz}$', '$\\kappa_{xx}/\\tau_0$[W/(m*K*s)]', '$\\kappa_{xy}$', 'k_xz', 'k_yx', 'k_yy', 'k_yz', 'k_zx', 'k_zy', 'k_zz' ] else: return ['EF', 'T', 'N', 'sigmaxx', 'sigmaxy', 'sigmaxz', 'sigmayx', 'sigmayy', 'sigmayz', 'sigmazx', 'sigmazy', 'sigmazz', 'Sxx', 'Sxy', 'Sxz', 'Syx', 'Syy', 'Syz', 'Szx', 'Szy', 'Szz', 'kxx', 'kxy', 'kxz', 'kyx', 'kyy', 'kyz', 'kzx', 'kzy', 'kzz' ]
[ドキュメント] def get_Tlist(self, data_list): """ データリストから重複しない温度のリストを抽出し、その数とともに返します。 :param data_list: BoltzTraP出力から読み込んだデータリスト(通常は2次元リスト)。 :type data_list: list of list :returns: (温度の数, 温度のリスト)。 :rtype: tuple (int, list of float) """ ndata = len(data_list) T_dic = {} for i in range(ndata): T_dic["{}".format(data_list[i])] = 1 T_list = [pfloat(key) for key in T_dic.keys()] return len(T_list), T_list
[ドキュメント] def get_EFlist(self, data_list): """ データリストから重複しないフェルミエネルギーのリストを抽出し、その数とともに返します。 :param data_list: BoltzTraP出力から読み込んだデータリスト(通常は2次元リスト)。 :type data_list: list of list :returns: (フェルミエネルギーの数, フェルミエネルギーのリスト)。 :rtype: tuple (int, list of float) """ ndata = len(data_list) EF_dic = {} for i in range(ndata): EF_dic["{}".format(data_list[i])] = 1 EF_list = [pfloat(key) for key in EF_dic.keys()] return len(EF_list), EF_list
[ドキュメント] def get_halltens_labels(self, latex_style = 0): """ BoltzTraPのホールテンソル (halltens) の列ラベルを取得します。 ホール係数に関するラベルが含まれます。 :param latex_style: このメソッドでは現在未使用ですが、将来の拡張のために含まれています。 :type latex_style: int :returns: ホールテンソルデータのラベルのリスト。 :rtype: list of str """ return ['EF', 'T', 'N', 'RHxxx', 'RHxxy', 'RHxxz', 'RHxyx', 'RHxyy', 'RHxyz', 'RHxzx', 'RHxzy', 'RHyzz', 'RHyxx', 'RHyxy', 'RHyxz', 'RHyyx', 'RHyyy', 'RHyyz', 'RHyzx', 'RHyzy', 'RHyzz', 'RHzxx', 'RHzxy', 'RHzxz', 'RHzyx', 'RHzyy', 'RHzyz', 'RHzzx', 'RHzzy', 'RHzzz' ]
[ドキュメント] def get_condtens_labels(self, latex_style = 0): """ BoltzTraPの伝導テンソル (condtens) の列ラベルを取得します。 電気伝導度、ゼーベック係数、熱伝導度に関するラベルが含まれます。 :param latex_style: ラベルをLaTeX形式にするかどうか。0の場合はプレーンテキスト。 :type latex_style: int :returns: 伝導テンソルデータのラベルのリスト。 :rtype: list of str """ if latex_style: return ['EF[Ry]', 'T[K]', 'N[e/uc]', '$\\sigma_{xx}/\\tau_0$[1/(ohm*m*s)]', 'sigma_xy', 'signma_xz', 'signma_yx', 'signma_yy', 'signma_yz', 'signma_zx', 'signma_zy', 'signma_zz', '$S_{xx}$[V/K]', '$S_{xy}$', '$S_{xz}$', '$S_{yx}$', '$S_{yy}$', '$S_{yz}$', '$S_{zx}$', '$S_{zy}$', '$S_{zz}$', '$\\kappa_{xx}/\\tau_0$[W/(m*K*s)]', '$\\kappa_{xy}$', 'k_xz', 'k_yx', 'k_yy', 'k_yz', 'k_zx', 'k_zy', 'k_zz' ] else: return ['EF', 'T', 'N', 'sigmaxx', 'sigmaxy', 'sigmaxz', 'sigmayx', 'sigmayy', 'sigmayz', 'sigmazx', 'sigmazy', 'sigmazz', 'Sxx', 'Sxy', 'Sxz', 'Syx', 'Syy', 'Syz', 'Szx', 'Szy', 'Szz', 'kxx', 'kxy', 'kxz', 'kyx', 'kyy', 'kyz', 'kzx', 'kzy', 'kzz' ]
[ドキュメント] def extract_data(self, labels, T_list, data_list, Vcell, mode): """ BoltzTraPの出力データから特定の輸送特性データを抽出します。 この関数は、与えられたラベルとモードに基づいて、フェルミエネルギー、温度、キャリア濃度、 および指定された輸送特性(sigma, S, kappa, RH, dos)を抽出して整形します。 :param labels: 全ての利用可能なラベルのリスト。 :type labels: list of str :param T_list: 抽出する温度のリスト。 :type T_list: list of float :param data_list: BoltzTraPの出力ファイルから読み込んだ生データ。 :type data_list: list of list of float :param Vcell: 単位胞の体積 (Å^3)。キャリア濃度やDOSの単位換算に使用されます。 :type Vcell: float :param mode: 抽出するデータの種類 ('all', 'sigma', 'S', 'kappa', 'RH', 'dos')。 :type mode: str :returns: (フェルミエネルギーの配列, 温度のリスト, キャリア濃度配列, 抽出されたデータ配列, 抽出されたデータのラベル)。 :rtype: tuple (numpy.ndarray, list of float, numpy.ndarray, numpy.ndarray, list of str) :raises SystemExit: 無効なモードが指定された場合。 """ ncol = len(data_list) ndata = len(data_list[0]) nT = len(T_list) nEF = int(ndata / nT + 1.0e-5) # EF = make_matrix1(nEF) # Ncm3 = make_matrix2(nT, nEF) EF = np.empty(nEF, dtype = float) Ncm3 = np.empty([nT, nEF], dtype = float) if mode == 'all': data = np.empty([nT, 27, nEF], dtype = float) idx0 = 3 idx1 = 29 plabels = labels[3:30] elif mode == 'sigma': data = np.empty([nT, 9, nEF], dtype = float) idx0 = 3 idx1 = 11 plabels = labels[3:12] elif mode == 'S': # data = make_matrix3(nT, 9, nEF) data = np.empty([nT, 9, nEF], dtype = float) idx0 = 12 idx1 = 20 plabels = labels[12:21] elif mode == 'kappa': # data = make_matrix3(nT, 9, nEF) data = np.empty([nT, 9, nEF], dtype = float) idx0 = 21 idx1 = 29 plabels = labels[21:30] elif mode == 'RH': # data = make_matrix3(nT, 9, nEF) data = np.empty([nT, 27, nEF], dtype = float) idx0 = 3 idx1 = 29 plabels = labels[3:30] elif mode == 'dos': data = np.empty([nT, 1, nEF], dtype = float) idx0 = 3 idx1 = 3 plabels = labels[3:4] else: terminate('Error in extract_data: Invalid mode [{}]'.format(mode), usage = usage) idxEF = 0 idxT = 1 idxN = 2 idxTot = 0 # print("data_list[i]=", data_list[0][0], data_list[0][1], data_list[0][2]) # print("n=", nEF, nT, ndata, idx0, idx1) #n= 2949 25 73725 3 11 for iEF in range(nEF): for iT in range(nT): if iT == 0: EF[iEF] = data_list[idxEF][idxTot] # print("EF=", iEF, EF[iEF]) Ncm3[iT][iEF] = data_list[idxN][iEF] / (Vcell * 1.0e-24) for idx in range(idx0, idx1+1): # print("idx=", iT, idx - idx0, iEF, idx, idxTot) data[iT][idx - idx0][iEF] = data_list[idx][idxTot] if mode == 'dos': data[iT][idx - idx0][iEF] /= Vcell * 1.0e-24 * RyToeV idxTot += 1 return EF, T_list.copy(), Ncm3, data, plabels
[ドキュメント] def read_btoutput(self, infile, E0 = 0.0, normalize_E = True, unit = '/cm3', EFmin = None, EFmax = None, print_level = 1, usage = None, exit_by_error = True): """ BoltzTraPの一般的な出力ファイル(.trace, .condtens, .halltensなど)を読み込みます。 フェルミエネルギーの正規化や範囲指定を行いながら、データを抽出します。 :param infile: 読み込むファイルのパス。 :type infile: str :param E0: エネルギーの基準点(Ry単位)。正規化する場合に使用されます。 :type E0: float :param normalize_E: フェルミエネルギーを `E0` を基準に正規化するかどうか。 :type normalize_E: bool :param unit: 現在は未使用ですが、将来の拡張のために含まれています。 :type unit: str :param EFmin: 抽出するフェルミエネルギーの下限 (eV単位)。 :type EFmin: float or None :param EFmax: 抽出するフェルミエネルギーの上限 (eV単位)。 :type EFmax: float or None :param print_level: ログ出力のレベル。 :type print_level: int :param usage: エラーメッセージに表示する使用法情報。 :type usage: str or None :param exit_by_error: ファイル読み込みエラー時にプログラムを終了するかどうか。 :type exit_by_error: bool :returns: (ヘッダーのリスト, データのリスト)。ファイル読み込み失敗時は (None, None)。 :rtype: tuple (list of str or None, list of list of float or None) """ # print("normalized:", normalize_E, E0) # exit() data_list = [] infp = tkFile(infile, "r") if infp.fp is None: if exit_by_error: terminate("Error: Can not read [{}]".format(infile), usage = usage) else: return None, None line = infp.ReadLine() header = line.split() # print("header=", header) count = 0 while 1: line = infp.ReadLine() if not line: break row = line.split() if count == 0: for j in range(len(row)): data_list.append([]) count += 1 if normalize_E: EF = pfloat(row[0]) * RyToeV - E0 else: EF = pfloat(row[0]) * RyToeV if EFmin is not None and EF < EFmin: continue if EFmax is not None and EFmax < EF: continue data_list[0].append(EF) for j in range(1, len(row)): data_list[j].append(pfloat(row[j])) infp.Close() return header, data_list
[ドキュメント] def read_intrans(self, infile, exit_by_error = True): """ BoltzTraPの入力設定ファイル (`*.intrans`) を読み込み、その内容を辞書として返します。 :param infile: 読み込む `*.intrans` ファイルのパス。 :type infile: str :param exit_by_error: ファイル読み込みエラー時にプログラムを終了するかどうか。 :type exit_by_error: bool :returns: intransファイルの内容を格納した辞書。ファイル読み込み失敗時は None。 :rtype: dict or None """ inf = {} infp = tkFile(infile, "r") if infp.fp is None: if exit_by_error: terminate("Error: Can not read [{}]".format(infile), usage = usage) else: return None inf = {} line = infp.ReadLine() aa = line.split() inf["interface"] = aa[0] aa = infp.ReadLine().split() inf["iskip"] = pint(aa[0]) inf["idebug"] = pint(aa[1]) inf["setgap"] = pint(aa[2]) inf["shiftgap"] = pfloat(aa[3]) aa = infp.ReadLine().split() inf["CALC"] = aa[0] aa = infp.ReadLine().split() inf["run_mode"] = aa[0] aa = infp.ReadLine().split() inf["EF_range"] = pfloat(aa[0]) aa = infp.ReadLine().split() inf["Tmax"] = pfloat(aa[0]) inf["Tstep"] = pfloat(aa[1]) aa = infp.ReadLine().split() inf["Erange_bands"] = pfloat(aa[0]) aa = infp.ReadLine().split() inf["LastLine"] = aa[0] infp.Close() return inf
[ドキュメント] def read_outputtrans(self, infile, exit_by_error = True): """ BoltzTraPの出力サマリーファイル (`*.outputtrans`) を読み込み、その内容を辞書として返します。 ケース名、バンドスタイル、フェルミエネルギー、ギャップエネルギー、VBM/CBMなどの情報を抽出します。 :param infile: 読み込む `*.outputtrans` ファイルのパス。 :type infile: str :param exit_by_error: ファイル読み込みエラー時にプログラムを終了するかどうか。 :type exit_by_error: bool :returns: outputtransファイルの内容を格納した辞書。ファイル読み込み失敗時は None。 :rtype: dict or None """ inf = {} infp = tkFile(infile, "r") if infp.fp is None: if exit_by_error: terminate("Error: Can not read [{}]".format(infile), usage = usage) else: return None line = infp.SkipTo(r'^\s*case\s+(\S+)') if line is not None: inf['case'] = infp.last_match[1] line = infp.SkipTo(r'^\s*Bandstyle:\s*(\S+)') if line is not None: inf['Bandstyle'] = infp.last_match[1] line = infp.SkipTo(r'^\s*Set fermi:\s*(\S+)') if line is not None: inf['Set_fermi'] = pint(infp.last_match[1]) line = infp.SkipTo(r'^\s*FermiE:\s*([+\-\d\.eEdD]+)\. ') if line is not None: s = infp.last_match[1] inf['FermiE'] = pfloat(s) line = infp.SkipTo(r'^\s*Run type:\s*(\S+)') if line is not None: inf['Run_type'] = infp.last_match[1] line = infp.SkipTo(r'^\s*Calc type:\s*(\S+)') if line is not None: inf['Calc_type'] = infp.last_match[1] line = infp.SkipTo(r'^\s*Number of kpts in IBZ:\s*(\S+)') if line is not None: inf['nkpts'] = pint(infp.last_match[1]) line = infp.SkipTo(r'^\s*Egap:\s*(\S+)') if line is not None: inf['Eg'] = pfloat(infp.last_match[1]) line = infp.SkipTo(r'^\s*VBM:\s*([+\-\d\.eEdD]+).+CBM:\s*([+\-\d\.eEdD]+).+Efermi:\s*([+\-\d\.eEdD]+)') if line is not None: inf['EVBM'] = pfloat(infp.last_match[1]) inf['ECBM'] = pfloat(infp.last_match[2]) inf['EF'] = pfloat(infp.last_match[3]) line = infp.SkipTo(r'^\s*KXMAX,KYMAX,KZMAX\s+([\d]+)\s+([\d]+)\s+([\d]+)') if line is not None: inf['KXMAX'] = pint(infp.last_match[1]) inf['KYMAX'] = pint(infp.last_match[2]) inf['KZMAX'] = pint(infp.last_match[3]) line = infp.SkipTo(r'^\s*GMAX\s+([\d]+)') if line is not None: inf['GMAX'] = pint(infp.last_match[1]) infp.Close() return inf
[ドキュメント] def read_transdos(self, infile, Vcell, SpinPolarized = False, E0 = None, normalize_E = True, unit = '/cm3', unit_N = '', Emin = None, Emax = None, print_level = 1, usage = None, exit_by_error = True): """ BoltzTraPの輸送DOSファイル (`*.transdos`) を読み込み、DOSとキャリア濃度情報を抽出します。 :param infile: 読み込む `*.transdos` ファイルのパス。 :type infile: str :param Vcell: 単位胞の体積 (Å^3)。DOSやキャリア濃度の単位換算に使用されます。 :type Vcell: float :param SpinPolarized: スピン分極計算かどうか。DOSとキャリア濃度のスケーリングに影響します。 :type SpinPolarized: bool :param E0: エネルギーの基準点。正規化する場合に使用されます。現在は未使用。 :type E0: float or None :param normalize_E: フェルミエネルギーを `E0` を基準に正規化するかどうか。現在は未使用。 :type normalize_E: bool :param unit: DOSの単位。'/cm3' の場合、単位胞の体積で割って体積あたりの値にします。 :type unit: str :param unit_N: キャリア濃度の単位。'/cm3' の場合、単位胞の体積で割って体積あたりの値にします。 :type unit_N: str :param Emin: 抽出するエネルギーの下限 (eV単位)。 :type Emin: float or None :param Emax: 抽出するエネルギーの上限 (eV単位)。 :type Emax: float or None :param print_level: ログ出力のレベル。 :type print_level: int :param usage: エラーメッセージに表示する使用法情報。 :type usage: str or None :param exit_by_error: ファイル読み込みエラー時にプログラムを終了するかどうか。 :type exit_by_error: bool :returns: transdosファイルから抽出された情報を格納した辞書。ファイル読み込み失敗時は None。 :rtype: dict or None """ inf = {} infp = tkFile(infile, "r") if infp.fp is None: if exit_by_error: terminate("Error: Can not read [{}]".format(infile), usage = usage) else: return None aa = infp.ReadLine().split() label, Estart, E2, Estep, xx, nE = aa[0], pfloat(aa[1]), pfloat(aa[2]), \ pfloat(aa[3]), pfloat(aa[4]), pint(aa[5]) if SpinPolarized: kN = 1.0 else: kN = 2.0 xE = [] yDOS = [] yN = [] for i in range(nE): aa = infp.ReadLine().split() aa[0] = pfloat(aa[0]) * RyToeV # if normalize_E and E0 is not None: # aa[0] -= E0 aa[1] = kN * pfloat(aa[1]) / RyToeV aa[2] = kN * pfloat(aa[2]) if unit == '/cm3': aa[1] = aa[1] / (Vcell * 1.0e-24) if unit_N == '/cm3': aa[2] = aa[2] / (Vcell * 1.0e-24) if Emin is not None and aa[0] < Emin: continue if Emax is not None and Emax < Emax: continue xE.append(aa[0]) yDOS.append(aa[1]) yN.append(aa[2]) infp.Close() Estart = xE[0] nE = len(xE) Eend = Estart + Estep * (nE - 1) inf = { "Estart": Estart, "Eend": Eend, "Estep": Estep, "nE": nE, "xE": xE, "dos": yDOS, 'yNcm3': yN } return inf
[ドキュメント] def read_trace(self, infile, Vcell, E0 = None, normalize_E = True, unit = '/cm3', EFmin = None, EFmax = None, print_level = 1, usage = None, exit_by_error = True): """ BoltzTraPのDOS補間ファイル (`*.trace`) を読み込み、DOS情報を抽出します。 このメソッドは `read_btoutput` を利用して生データを読み込み、`extract_data` でDOS情報を整形します。 :param infile: 読み込む `*.trace` ファイルのパス。 :type infile: str :param Vcell: 単位胞の体積 (Å^3)。DOSの単位換算に使用されます。 :type Vcell: float :param E0: エネルギーの基準点(Ry単位)。正規化する場合に使用されます。 :type E0: float or None :param normalize_E: フェルミエネルギーを `E0` を基準に正規化するかどうか。 :type normalize_E: bool :param unit: 現在は未使用ですが、将来の拡張のために含まれています。 :type unit: str :param EFmin: 抽出するフェルミエネルギーの下限 (eV単位)。 :type EFmin: float or None :param EFmax: 抽出するフェルミエネルギーの上限 (eV単位)。 :type EFmax: float or None :param print_level: ログ出力のレベル。 :type print_level: int :param usage: エラーメッセージに表示する使用法情報。 :type usage: str or None :param exit_by_error: ファイル読み込みエラー時にプログラムを終了するかどうか。 :type exit_by_error: bool :returns: traceファイルから抽出されたDOS情報を格納した辞書。ファイル読み込み失敗時は None。 :rtype: dict or None """ header0, data_list = self.read_btoutput(infile, E0 = E0, normalize_E = normalize_E, unit = unit, EFmin = EFmin, EFmax = EFmax, print_level = print_level, usage = usage, exit_by_error = exit_by_error) if header0 is None or data_list is None or len(data_list) < 5: return None labels = self.get_condtens_labels() nT, T_list = self.get_Tlist(data_list[1]) nEF, EF_list = self.get_Tlist(data_list[0]) xEF, xT, yNcm3, doslist, dos_labels = self.extract_data(labels, T_list, data_list, Vcell, 'dos') inf = { 'header': header0, 'data_list': data_list, 'labels': labels, 'ncolumns': len(data_list), 'ndata': len(data_list[0]), 'nT': nT, 'T_list': T_list, 'nEF': nEF, 'EF_list': EF_list, 'xEF': xEF, 'xT': xT, 'yNcm3': yNcm3, 'dos': doslist, 'dos_label': 'DOS' } return inf
[ドキュメント] def read_condtens(self, infile, Vcell, E0 = None, normalize_E = True, unit = '/cm3', EFmin = None, EFmax = None, print_level = 1, usage = None, exit_by_error = True): """ BoltzTraPの輸送テンソルファイル (`*.condtens`) を読み込み、伝導特性を抽出します。 このメソッドは `read_btoutput` を利用して生データを読み込み、`extract_data` で電気伝導度、 ゼーベック係数、熱伝導度などの情報を整形します。 :param infile: 読み込む `*.condtens` ファイルのパス。 :type infile: str :param Vcell: 単位胞の体積 (Å^3)。キャリア濃度の単位換算に使用されます。 :type Vcell: float :param E0: エネルギーの基準点(Ry単位)。正規化する場合に使用されます。 :type E0: float or None :param normalize_E: フェルミエネルギーを `E0` を基準に正規化するかどうか。 :type normalize_E: bool :param unit: 現在は未使用ですが、将来の拡張のために含まれています。 :type unit: str :param EFmin: 抽出するフェルミエネルギーの下限 (eV単位)。 :type EFmin: float or None :param EFmax: 抽出するフェルミエネルギーの上限 (eV単位)。 :type EFmax: float or None :param print_level: ログ出力のレベル。 :type print_level: int :param usage: エラーメッセージに表示する使用法情報。 :type usage: str or None :param exit_by_error: ファイル読み込みエラー時にプログラムを終了するかどうか。 :type exit_by_error: bool :returns: condtensファイルから抽出された伝導特性情報を格納した辞書。ファイル読み込み失敗時は None。 :rtype: dict or None """ header0, data_list = self.read_btoutput(infile, E0 = E0, normalize_E = normalize_E, unit = unit, EFmin = EFmin, EFmax = EFmax, print_level = print_level, usage = usage, exit_by_error = exit_by_error) if header0 is None or data_list is None or len(data_list) < 2: return None labels = self.get_condtens_labels() nT, T_list = self.get_Tlist(data_list[1]) nEF, EF_list = self.get_Tlist(data_list[0]) xEF, xT, yNcm3, sigmalist, sigma_labels = self.extract_data(labels, T_list, data_list, Vcell, 'sigma') xEF, xT, yNcm3, Slist, S_labels = self.extract_data(labels, T_list, data_list, Vcell, 'S') xEF, xT, yNcm3, kappalist, kappa_labels = self.extract_data(labels, T_list, data_list, Vcell, 'kappa') inf = { 'header': header0, 'data_list': data_list, 'labels': labels, 'ncolumns': len(data_list), 'ndata': len(data_list[0]), 'nT': nT, 'T_list': T_list, 'nEF': nEF, 'EF_list': EF_list, 'xEF': xEF, 'xT': xT, 'yNcm3': yNcm3, 'sigma': sigmalist, 'sigma_label': sigma_labels, 'S': Slist, 'S_label': S_labels, 'kappa': kappalist, 'kappa_label': kappa_labels } return inf
[ドキュメント] def read_halltens(self, infile, Vcell, E0 = None, normalize_E = True, unit = '/cm3', EFmin = None, EFmax = None, print_level = 1, usage = None, exit_by_error = True): """ BoltzTraPのホールテンソルファイル (`*.halltens`) を読み込み、ホール係数を抽出します。 このメソッドは `read_btoutput` を利用して生データを読み込み、`extract_data` でホール係数情報を整形します。 :param infile: 読み込む `*.halltens` ファイルのパス。 :type infile: str :param Vcell: 単位胞の体積 (Å^3)。キャリア濃度の単位換算に使用されます。 :type Vcell: float :param E0: エネルギーの基準点(Ry単位)。正規化する場合に使用されます。 :type E0: float or None :param normalize_E: フェルミエネルギーを `E0` を基準に正規化するかどうか。 :type normalize_E: bool :param unit: 現在は未使用ですが、将来の拡張のために含まれています。 :type unit: str :param EFmin: 抽出するフェルミエネルギーの下限 (eV単位)。 :type EFmin: float or None :param EFmax: 抽出するフェルミエネルギーの上限 (eV単位)。 :type EFmax: float or None :param print_level: ログ出力のレベル。 :type print_level: int :param usage: エラーメッセージに表示する使用法情報。 :type usage: str or None :param exit_by_error: ファイル読み込みエラー時にプログラムを終了するかどうか。 :type exit_by_error: bool :returns: halltensファイルから抽出されたホール係数情報を格納した辞書。ファイル読み込み失敗時は None。 :rtype: dict or None """ header0, data_list = self.read_btoutput(infile, E0 = E0, normalize_E = normalize_E, unit = unit, EFmin = EFmin, EFmax = EFmax, print_level = print_level, usage = usage, exit_by_error = exit_by_error) if header0 is None or data_list is None or len(data_list) < 2: return None labels = self.get_halltens_labels() nT, T_list = self.get_Tlist(data_list[1]) nEF, EF_list = self.get_Tlist(data_list[0]) xEF, xT, yNcm3, RHlist, RH_labels = self.extract_data(labels, T_list, data_list, Vcell, 'RH') inf = { 'header': header0, 'data_list': data_list, 'labels': labels, 'ncolumns': len(data_list), 'ndata': len(data_list[0]), 'nT': nT, 'T_list': T_list, 'nEF': nEF, 'EF_list': EF_list, 'xEF': xEF, 'xT': xT, 'yNcm3': yNcm3, 'RH': RHlist, 'RH_label': RH_labels } return inf
[ドキュメント] def getdir(self, path): """ 与えられたパスがディレクトリであればそのパスを返し、そうでなければそのパスのディレクトリ部分を返します。 :param path: チェックするファイルまたはディレクトリのパス。 :type path: str :returns: ディレクトリのパス。 :rtype: str """ if IsDir(path): return path dirname, basename, filebody, ext = SplitFilePath(path) return dirname
[ドキュメント] def get_INCAR(self, CAR_dir): """ INCARファイルの完全なパスを取得します。 :param CAR_dir: INCARファイルが格納されているディレクトリのパス。 :type CAR_dir: str :returns: INCARファイルの完全なパス。 :rtype: str """ return os.path.join(CAR_dir, 'INCAR')
[ドキュメント] def find_band_edges_from_dos(self, E, DOS, EF0 = 0.0, DOSth = 1.0e18): """ DOS (状態密度) データから価電子帯上端 (EV) と伝導帯下端 (EC) を推定します。 フェルミエネルギーを基準に、DOSが閾値 `DOSth` を超える点でバンド端を特定します。 :param E: エネルギーのリスト (eV)。 :type E: list of float :param DOS: 対応する状態密度のリスト。 :type DOS: list of float :param EF0: 基準となるフェルミエネルギー (eV)。 :type EF0: float :param DOSth: バンド端と見なすDOSの閾値。 :type DOSth: float :returns: (価電子帯上端のエネルギー, 伝導帯下端のエネルギー)。 :rtype: tuple (float, float) """ EV = 1.0e30 EC = 1.0e30 i0 = -1 for i in range(len(E)): # print("i=", i, E[i], EF0) if E[i] >= EF0: i0 = i break for i in range(i0, 0, -1): # print("i2=", i, DOS[i], DOSth) if DOS[i] > DOSth: EV = E[i+1] break for i in range(i0, len(E), +1): # print("i3=", i, DOS[i], DOSth) if DOS[i] > DOSth: EC = E[i-1] break return EV, EC
[ドキュメント] def find_band_edges_from_eigenval(self, EF0 = 0.0, eigenvalinf = None, ISPIN = None): """ EIGENVALデータから価電子帯上端 (EV) と伝導帯下端 (EC) を推定します。 k点ごとのバンドエネルギーと占有数を用いて、EHOMO (Highest Occupied Molecular Orbital) と ELUMO (Lowest Unoccupied Molecular Orbital) も合わせて計算します。 :param EF0: 基準となるフェルミエネルギー (eV)。Noneの場合、0.0が使用されます。 :type EF0: float or None :param eigenvalinf: EIGENVALファイルから読み込んだ情報を含む辞書。Noneの場合、`self.eigenvalinf` を使用します。 :type eigenvalinf: dict or None :param ISPIN: スピン分極計算かどうか (1: 非スピン分極, 2: スピン分極)。Noneの場合、`self.outcarinf` または `self.incarinf` から取得を試みます。 :type ISPIN: int or None :returns: バンド端情報 (EV, EC, Eg, EF0, EHOMO, ELUMO) を含む辞書。 :rtype: dict """ if ISPIN is None: if self.outcarinf: ISPIN = self.outcarinf["ISPIN"] elif self.incarinf: ISPIN = self.incarinf["ISPIN"] else: ISPIN = 1 if EF0 is None: EF0 = 0.0 if eigenvalinf is None: eigenvalinf = self.eigenvalinf EPS = 1.0e-3 nk = eigenvalinf["nk"] nLevels = eigenvalinf["nLevels"] EV = -1e100 EC = 1e100 # print("k points in EIGENVAL:") # print("nk=", nk) # print("nLevels=", nLevels) EHOMO = -1.0e10 ELUMO = 1.0e10 EList = eigenvalinf['EList'] for i in range(len(EList)): el = EList[i] kx, ky, kz, wk, dk, ktot, Eups, occups, Edns, occdns = el # print(" ({:8.4f} {:8.4f} {:8.4f}) w={:8.4g} {:8.4f} {:12.4f}" # .format(kx, ky, kz, wk, dk, ktot)) for il in range(nLevels): # print(" il={} E={} occ={}".format(il, Eups[il], occups[il])) if occups[il] > 0.0 and EHOMO < Eups[il]: EHOMO = Eups[il] if occups[il] <= 0.0 and ELUMO > Eups[il]: ELUMO = Eups[il] if Eups[il] < EF0 + EPS and EV < Eups[il]: EV = Eups[il] # print("EV=>", i, EV+EF, kx, ky, kz) if Eups[il] > EF0 - EPS and EC > Eups[il]: EC = Eups[il] if ISPIN == 2: if occdns[il] > 0.0 and EHOMO < Edns[il]: EHOMO = Edns[il] if occdns[il] <= 0.0 and ELUMO > Edns[il]: ELUMO = Edns[il] if Edns[il] < EF0 + EPS and EV < Edns[il]: EV = Edns[il] # print("EV=>", i, EV+EF, kx, ky, kz) if Edns[il] > EF0 - EPS and EC > Edns[il]: EC = Edns[il] # print("EC=>", i, EC+EF, kx, ky, kz) # print("EV=", i, il, EV) inf = { "EV": EV, "EC": EC, "Eg": EC - EV, "EF0": EF0, "EHOMO": EHOMO, "ELUMO": ELUMO } return inf
[ドキュメント] def read_doscar(self, DOSCAR_path, cry = None, IsSpinPolarized = None, IsNonCollinear = None, EF = None, unit = ''): """ VASPのDOSCARファイルを読み込み、全状態密度 (TotalDOS) およびスピンごとの状態密度 (DOSup, DOSdn) とキャリア濃度 (Ne, Neup, Nedn) を抽出します。 エネルギーはフェルミエネルギー `EF` を基準にシフトされます。 :param DOSCAR_path: DOSCARファイルのパス。 :type DOSCAR_path: str :param cry: 結晶オブジェクト。単位胞の体積 (`cry.Volume()`) を取得するために使用されます。Noneの場合、`self.crystal` を使用します。 :type cry: tkCrystalObject or None :param IsSpinPolarized: スピン分極計算かどうか (True/False)。Noneの場合、`self.outcarinf["ISPIN"]` を使用します。 :type IsSpinPolarized: bool or None :param IsNonCollinear: 非共線スピン計算かどうか (True/False)。現在は未使用。 :type IsNonCollinear: bool or None :param EF: フェルミエネルギー (eV)。Noneの場合、`self.outcarinf["EF"]` を使用します。 :type EF: float or None :param unit: DOSの単位。'/cm3' の場合、単位胞の体積で割って体積あたりの値にします。 :type unit: str :returns: DOSCARファイルから抽出された情報を格納した辞書。ファイル読み込み失敗時は一部のキーが空の辞書。 :rtype: dict """ if EF is None: EF = self.outcarinf["EF"] if cry is None: cry = self.crystal if IsSpinPolarized is None: IsSpinPolarized = self.outcarinf["ISPIN"] if IsNonCollinear is None: try: IsNonCollinear = cry.outcarinf["LCOLLINEAR"] except: IsNonCollinear = 0 inf = {} fp = tkFile(DOSCAR_path, 'r') if not fp or fp.fp is None: # terminate("Error in read_average_core_potentials: Can not read [{}]".format(DOSCAR_path)) return { "nE": 0, "E": [], "TotalDOSup": [], "TotalDOSdn": [], "Neup": [], "Nedn": [] } # if(!defined $IsNonCollinear) { # my $INCAR = $this->GetINCARFileName($path); # my $pINCAR = $this->ReadINCARtoHash($INCAR); # $IsNonCollinear = ($pINCAR->{LSORBIT} =~ /[1T]/i or $pINCAR->{LNONCOLLINEAR} =~ /[1T]/i)? 1 : 0; # $IsSpinPolarized = 0 if($IsNonCollinear); # } for i in range(5): line = fp.ReadLine() inf["SampleName"] = line.strip() # print("s=", inf["SampleName"]) line = fp.ReadLine() aa = line.split() nData = pint(aa[2]) # print("nData=", nData) Elist = [] tDOSuplist = [] tDOSdnlist = [] tDOSlist = [] Nelist = [] Neuplist = [] Nednlist = [] for i in range(nData): line = fp.ReadLine() if not line: break aa = line.split() if len(aa) == 0: break elif len(aa) <= 3: SpinPolarized = 0 du = pfloat(aa[1]) nu = pfloat(aa[2]) dd = 0.0 nd = 0.0 else: SpinPolarized = 1 du = pfloat(aa[1]) dd = pfloat(aa[2]) nu = 0.0 nd = 0.0 e = pfloat(aa[0]) Elist.append(e - EF) tDOSuplist.append(du) tDOSdnlist.append(dd) Neuplist.append(nu) Nednlist.append(du) # print("e=",e, du, nu) fp.Close() nE = len(Elist) if SpinPolarized == 1: # print("n=", len(tDOSuplist), len(tDOSdnlist)) Neuplist = rieman_array_func(Elist, tDOSuplist) Nednlist = rieman_array_func(Elist, tDOSdnlist) if unit == '/cm3': Vcell = cry.Volume() for i in range(nE): k = 1.0 / (Vcell * 1.0e-24) tDOSuplist[i] *= k Neuplist[i] *= k if SpinPolarized == 1: tDOSdnlist[i] *= k Neuplist[i] *= k for i in range(nE): if SpinPolarized == 0: tDOSlist.append(tDOSuplist[i]) Nelist.append(Neuplist[i]) else: tDOSlist.append(tDOSuplist[i] + tDOSdnlist[i]) Nelist.append(Neuplist[i] + Nednlist[i]) inf["nE"] = nE inf["E"] = Elist inf["TotalDOS"] = tDOSlist inf["TotalDOSup"] = tDOSuplist inf["TotalDOSdn"] = tDOSdnlist inf["Ne"] = Nelist inf["Neup"] = Neuplist inf["Nedn"] = Nednlist return inf
[ドキュメント] def read_files(self, file, file_types, exit_by_error = False, print_level = 0, terminate = terminate): """ 指定されたVASP関連ファイルを一括で読み込み、その情報を辞書として返します。 読み込むファイルのタイプを `file_types` リストで指定できます。 `tkCrystalObject` から継承された `read_incar_inf`, `read_potcar_inf`, `read_poscar`, `read_outcar_inf`, `read_eigenval` などのメソッドを利用します。 :param file: 基準となるファイルパス(ディレクトリを特定するために使用)。 :type file: str :param file_types: 読み込むファイルの種類を示す文字列のリスト(例: ['INCAR', 'OUTCAR'])。 :type file_types: list of str :param exit_by_error: ファイル読み込みエラー時にプログラムを終了するかどうか。 :type exit_by_error: bool :param print_level: ログ出力のレベル。1以上で読み込み状況が表示されます。 :type print_level: int :param terminate: エラー発生時に呼び出す終了関数。 :type terminate: callable :returns: 読み込んだファイルの情報を含む辞書。各キーはファイルタイプ(例: 'INCAR')。 :rtype: dict """ base_path = self.getdir(file) INCAR_path = self.get_INCAR(base_path) POSCAR_path = self.get_POSCAR(base_path) POTCAR_path = self.get_POTCAR(base_path) CONTCAR_path = self.get_CONTCAR(base_path) OUTCAR_path = self.get_OUTCAR(base_path) EIGENVAL_path = self.get_VASPPath(base_path, 'EIGENVAL') DOSCAR_path = self.get_VASPPath(base_path, 'DOSCAR') if print_level >= 1: print("") print("CAR dir : ", base_path) print(" INCAR : ", INCAR_path) print(" POSCAR : ", POSCAR_path) print(" POTCAR : ", POTCAR_path) print(" CONTCAR : ", CONTCAR_path) print(" OUTCAR : ", OUTCAR_path) print(" EIGENVAL: ", EIGENVAL_path) print(" DOSCAR : ", DOSCAR_path) inf = {} if 'INCAR' in file_types: if print_level >= 1: print("*** Read INCAR from [{}]".format(INCAR_path)) inf["INCAR"] = self.read_incar_inf(INCAR_path) if exit_by_error and inf["INCAR"] is None: terminate("Error in tkvasp.read_files: Can not read [{}]".format(INCAR_path)) if 'POTCAR' in file_types: if print_level >= 1: print("*** Read POTCAR from [{}]".format(POTCAR_path)) inf["POTCAR"] = self.read_potcar_inf(POTCAR_path) if exit_by_error and inf["POTCAR"] is None: terminate("Error in tkvasp.read_files: Can not read [{}]".format(POTCAR_path)) if 'POSCAR' in file_types: if print_level >= 1: print("*** Read crystal structure from [{}]".format(POSCAR_path)) inf["POSCAR"] = self.read_poscar(POSCAR_path) if exit_by_error and inf["POSCAR"] is None: terminate("Error in tkvasp.read_files: Can not read [{}]".format(POSCAR_path)) if 'CONTCAR' in file_types: if print_level >= 1: print("*** Read crystal structure from [{}]".format(CONTCAR_path)) inf["CONTCAR"] = self.read_poscar(CONTCAR_path) if exit_by_error and inf["POSCAR"] is None: terminate("Error in tkvasp.read_files: Can not read [{}]".format(CONTCAR_path)) if 'OUTCAR' in file_types: if print_level >= 1: print("*** Read OUTCAR from [{}]".format(OUTCAR_path)) inf["OUTCAR"] = self.read_outcar_inf(OUTCAR_path) if exit_by_error and inf["OUTCAR"] is None: terminate("Error in tkvasp.read_files: Can not read [{}]".format(OUTCAR_path)) if 'DOSCAR' in file_types: if print_level >= 1: print("*** Read DOSCAR from [{}]".format(DOSCAR_path)) inf["DOSCAR"] = self.read_doscar(DOSCAR_path) if exit_by_error and inf["DOSCAR"] is None: terminate("Error in tkvasp.read_files: Can not read [{}]".format(DOSCAR_path)) if 'EIGENVAL' in file_types: if print_level >= 1: print("*** Read EIGENVAL from [{}]".format(EIGENVAL_path)) inf["EIGENVAL"] = self.read_eigenval(EIGENVAL_path) if exit_by_error and inf["EIGENVAL"] is None: terminate("Error in tkvasp.read_files: Can not read [{}]".format(EIGENVAL_path)) return inf