"""
概要: 重み付き移動度とキャリア濃度を計算し、関連する解析を行うスクリプト。
詳細説明: このスクリプトは、伝導率とゼーベック係数から重み付き移動度とキャリア濃度を算出します。
単一点計算、結果の検証、温度依存性、組成依存性の解析機能を含みます。
また、計算に必要な物理定数とパラメータが定義されています。
関連リンク: :doc:`tktransport.tkWeightedMobility`
"""
import sys
import os
import re
import numpy as np
from numpy import sqrt, exp, log, sin, cos, tan, pi
import numpy.linalg as LA
from matplotlib import pyplot as plt
from tklib.tkutils import pint, pfloat, getarg, getintarg, getfloatarg
from tklib.tkvariousdata import tkVariousData
from tklib.tkapplication import tkApplication
from tklib.tksci.tksci import e, pi, kB
from tklib.tktransport.tkDOS_FEA import integrate_Simpson, integrate_Simpson_list, tkDOS
from tklib.tktransport.tkTransport import FermiIntegral_fast as FermiIntegral
from tklib.tktransport.tkTransport import integrate_Simpson_list, fe, fh, meff2NC_FEA, meff2DC0_FEA, BMShift_FEA
from tklib.tktransport.tkWeightedMobility import weighted_mobility, weighted_mobility_new, weighted_mobility_exact
from tklib.tktransport.tkTransport import LorentzNumber_FEA
#===================================
# physical constants
#===================================
pi = 3.14159265358979323846
pi2 = 2.0 * pi
h = 6.6260755e-34 # Js";
hbar = 1.05459e-34 # "Js";
c = 2.99792458e8 # m/s";
e = 1.60218e-19 # C";
e0 = 8.854418782e-12; # C<sup>2</sup>N<sup>-1</sup>m<sup>-2</sup>";
kB = 1.380658e-23 # JK<sup>-1</sup>";
me = 9.1093897e-31 # kg";
R = 8.314462618 # J/K/mol
a0 = 5.29177e-11 # m";
#===================================
# parameters
#===================================
app = None
# mode: 'single', 'X', 'T'
mode = 'single'
# Temperature (K)
T0 = 300.0
# calculation type
cal_type = 'exact' # 'approx', 'Snyder'
# scattering factor
r0 = 0.0
# DOS effective mass
meffDOS0 = 1.0
# For mode == 'single'
sigma0 = 95.0 # S/cm
S0 = 28.0e-6 # V/S
# For mode == 'X' and 'T'
# Input and output files
infile = 'LaTiO3-sigma-S-T.xlsx'
outfile = None
# Indexes of columns for X variable, T, sigma (S/cm), and S (V/K)
X_label = 0
T_label = 0
sigma_label = 1
S_label = 2
#===================================
# figure configuration
#===================================
figsize = (12, 8)
fontsize = 16
legend_fontsize = 12
markersize = 4.0
#===================================
# Treat arguments
#===================================
[ドキュメント]
def modify_path(path, addpath):
"""
概要: ファイルパスに指定された文字列を追加して新しいパスを生成します。
詳細説明: 入力パスのファイル名部分(拡張子の前)に `addpath` を追加し、新しいファイルパスを返します。
この関数はファイル名の本体部分に `addpath` を直接連結するため、
元のファイルの拡張子は失われます。`addpath` に拡張子を含めることで対応可能です。
:param path: str: 元のファイルパス。
:param addpath: str: ファイル名に追加する文字列(例: '-out.xlsx')。
:returns: str: 変更された新しいファイルパス。
"""
basename = os.path.basename(path)
dirname = os.path.dirname(path)
header, ext = os.path.splitext(path)
filebody = os.path.basename(header)
return os.path.join(dirname, filebody + addpath)
[ドキュメント]
def usage(app = None):
"""
概要: スクリプトのコマンドライン引数の使用方法を表示します。
詳細説明: スクリプトの実行モード('check', 'single', 'X', 'T')に応じた引数の例とともに、標準出力に表示します。
不正な引数でスクリプトが実行された場合などに呼び出されます。
:param app: tklib.tkapplication.tkApplication, optional: アプリケーションインスタンス。デフォルトはNone。
:returns: None
"""
argv = sys.argv
print("")
print("Usage: python {} check T r".format(argv[0]))
print(" ex: python {} check {}".format(argv[0], T0, r0))
print(" ex: python {} single {} {} {} {} {}".format(argv[0], sigma0, S0, T0, meffDOS0, r0))
print("Usage: python {} single sigma(S/cm) S(V/K) T(K) r".format(argv[0]))
print("Usage: python {} X infile T(K) X_label sigma_label S_label".format(argv[0]))
print(" ex: python {} X {} {} {} {} {}".format(argv[0], infile, T0, X_label, sigma_label, S_label))
print("Usage: python {} T infile iT isigma iS".format(argv[0]))
print(" ex: python {} T {} {} {} {}".format(argv[0], infile, T_label, sigma_label, S_label))
[ドキュメント]
def updatevars():
"""
概要: コマンドライン引数からグローバル変数を更新します。
詳細説明: `sys.argv` から引数を解析し、`mode`, `T0`, `meffDOS0`, `r0`, `sigma0`, `S0`, `infile`, `outfile`,
`X_label`, `T_label`, `sigma_label`, `S_label` などのグローバル変数を設定します。
無効なモードが指定された場合はエラーメッセージを表示し、アプリケーションを終了します。
:returns: None
"""
global mode, cal_type
global T0, meffDOS0, r0
global sigma0, S0
global infile, outfile
global X_label, T_label, sigma_label, S_label
argv = sys.argv
mode = getarg( 1, mode)
if mode == 'check':
T0 = getfloatarg( 2, T0)
r0 = getfloatarg( 3, r0)
elif mode == 'single':
sigma0 = getfloatarg( 2, sigma0)
S0 = getfloatarg( 3, S0)
T0 = getfloatarg( 4, T0)
meffDOS0 = getfloatarg( 5, meffDOS0)
r0 = getfloatarg( 6, r0)
elif mode == 'X':
infile = getarg ( 2, infile)
T0 = getfloatarg( 3, T0)
cal_type = getarg ( 4, cal_type)
meffDOS0 = getfloatarg( 5, meffDOS0)
r0 = getfloatarg( 6, r0)
X_label = getarg ( 7, X_label)
sigma_label = getarg ( 8, sigma_label)
S_label = getarg ( 9, S_label)
outfile = modify_path(infile, '-out.xlsx')
elif mode == 'T':
infile = getarg ( 2, infile)
cal_type = getarg ( 3, cal_type)
meffDOS0 = getfloatarg( 4, meffDOS0)
r0 = getfloatarg( 5, r0)
T_label = getarg ( 6, T_label)
sigma_label = getarg ( 7, sigma_label)
S_label = getarg ( 8, S_label)
outfile = modify_path(infile, '-out.xlsx')
else:
app.terminate("Error: Invalid mode [{}]".format(mode), usage = usage, pause = True)
#===================================
# Other functions
#===================================
[ドキュメント]
def read_file(fname):
"""
概要: 指定されたファイルからデータを読み込みます。
詳細説明: `tkVariousData` クラスを使用して、指定されたファイルからラベルとデータリストを読み取ります。
ファイル読み込み後、ファイルポインタは閉じられます。
:param fname: str: 読み込むファイルの名前。
:returns: tuple: (tklib.tkvariousdata.tkVariousData, list, list): データファイルオブジェクト、ラベルのリスト、データリスト。
"""
print("")
datafile = tkVariousData(infile)
labels, datalist = datafile.Read_minimum_matrix(close_fp=True, usage=usage)
return datafile, labels, datalist
[ドキュメント]
def validate_data(list, desc):
"""
概要: 与えられたデータリストが`None`でないことを検証します。
詳細説明: データリストが`None`の場合、エラーメッセージを出力し、アプリケーションを終了します。
:param list: list: 検証するデータリスト。
:param desc: str: データリストの説明。エラーメッセージで使用されます。
:returns: None
"""
if list is None:
app.terminate(f"\nError in validate_data: Null data for {desc}\n", pause=True)
[ドキュメント]
def exec_single():
"""
概要: 単一点の重み付き移動度とキャリア濃度を計算します。
詳細説明: 指定された伝導率 (sigma0)、ゼーベック係数 (S0)、温度 (T0)、DOS有効質量 (meffDOS0)、
および散乱因子 (r0) を用いて、スナイダーの式、自由電子モデルの近似式、
および厳密解に基づいて重み付き移動度とキャリア濃度を計算し、結果を標準出力に表示します。
計算された移動度とキャリア濃度は、Snyderの式、DOS有効質量補正、自由電子モデル近似、自由電子モデル厳密解の各ケースで出力されます。
:returns: None
"""
'''
dos = tkDOS()
dos.EV = 0.0
dos.EC = 3.0
dos.mheff = meffDOS0
dos.meeff = meffDOS0
dos.NV = meff2NC_FEA(dos.mheff, T0)
dos.NC = meff2NC_FEA(dos.meeff, T0)
dos.DV0 = meff2DC0_FEA(dos.mheff, T0)
dos.DC0 = meff2DC0_FEA(dos.meeff, T0)
dos.EA = 0.05
dos.NA = 0.0
dos.ED = 2.95
dos.ND = 0.0
dos.EF0 = 0.1
# mobility.meff = dos.meeff
# mobility.l0 = 1.0e-10
# mobility.charge = 1.0
# mobility.rfac = 0.0
mu = 1.0
'''
EV = 0.0
EC = 3.0
EFmin = EV - 5.0
EFmax = EC + 0.5
eps = 1.0e-10
nmaxiter = 1000
print_level = 0
print("")
print(f"sigma = {sigma0} S/cm")
print(f"S = {S0} V/K")
print(f"T = {T0} K")
print(f"m*(DOS)= {meffDOS0} me")
print(f"r = {r0}")
print(f" Note: Snyder's eq assumes m*(DOS) = 1.0 and r = 0.0")
muw, nw, sign, carriertype = weighted_mobility (sigma0 * 100.0, S0, T0, unit = 'm')
muw2, nw2, s2, ct2 = weighted_mobility_new (sigma0 * 100.0, S0, T0, meff = meffDOS0, r = r0, unit = 'm')
muwe, nwe, s, ct, EF = weighted_mobility_exact(sigma0 * 100.0, S0, T0, meff = meffDOS0, r = r0, polarity = 'h',
EFmin = EFmin, EFmax = EFmax, eps = eps, nmaxiter = nmaxiter, print_level = print_level, unit = 'm')
print("")
print("Majority carrier type:", carriertype)
print("Snyder's weighted mobility")
print(f" mu_w = {muw:12.6g} m^2/(Vs) = {muw * 1.0e4:12.6g} cm^2/(Vs)")
print(f" n_w = {nw:12.6g} m^-3 = {nw * 1.0e-6:12.6g} cm^-3")
print(f" m*(DOS) corrected values:")
k = pow(meffDOS0, 1.5)
print(f" mu = {muw / k:12.6g} m^2/(Vs) = {muw / k * 1.0e4:12.6g} cm^2/(Vs)")
print(f" n = {nw * k :12.6g} m^-3 = {nw * k * 1.0e-6:12.6g} cm^-3")
print("Free electron model weighted mobility approximation")
print(f" mu = {muw2:12.6g} m^2/(Vs) = {muw2 * 1.0e4:12.6g} cm^2/(Vs)")
print(f" n = {nw2:12.6g} m^-3 = {nw2 * 1.0e-6:12.6g} cm^-3")
print("Free electron model weighted mobility exact")
print(f" mu = {muwe:12.6g} m^2/(Vs) = {muwe * 1.0e4:12.6g} cm^2/(Vs)")
print(f" n = {nwe:12.6g} m^-3 = {nwe * 1.0e-6:12.6g} cm^-3")
print("")
app.terminate(pause = True)
[ドキュメント]
def exec_check():
"""
概要: 重み付き移動度の計算結果を検証します。
詳細説明: 現在の温度 (T0) と散乱因子 (r0) に基づいて、ゼーベック係数とフェルミ準位の依存性を計算し、
非縮退、縮退、厳密なモデルでのゼーベック係数を比較します。
様々な重み付き移動度の計算結果をExcelファイルに保存し、
さらに、S/(kB/e) と f (f_deg, f_non-deg) の関係、
EF と S (S_exact, S_deg, S_non-deg) の関係のグラフをプロットします。
:returns: None
"""
T = T0
r = r0
Skemin = 0.05
Skemax = 10.0
nSke = 1001
logSkestep = (log(Skemax) - log(Skemin)) / (nSke - 1)
print()
print("Check weighted mobility results")
print(" T={T} K")
print(" r={0.0 for Snyder equations")
print(" r={r} for Boltzmann transport thoery")
dos = tkDOS()
dos.EV = 0.0
dos.EC = 3.0
dos.mheff = 1.0
dos.meeff = 1.0
dos.NV = meff2NC_FEA(dos.mheff, T)
dos.NC = meff2NC_FEA(dos.meeff, T)
dos.DV0 = meff2DC0_FEA(dos.mheff, T)
dos.DC0 = meff2DC0_FEA(dos.meeff, T)
dos.EA = 0.05
dos.NA = 0.0
dos.ED = 2.95
dos.ND = 0.0
dos.EF0 = 0.1
# mobility.meff = dos.meeff
# mobility.l0 = 1.0e-10
# mobility.charge = 1.0
# mobility.rfac = 0.0
mu = 1.0
EFmin = dos.EV - 5.0
EFmax = dos.EC + 0.5
eps = 1.0e-10
nmaxiter = 1000
print_level = 0
print("")
print(f"T: {T} K")
print(f"Electronic structure:")
print(f"EV={dos.EV} EC={dos.EC} Eg={dos.EC-dos.EV} eV")
print(f"Accecptor: {dos.NA} cm-3 at EV + {dos.EA} eV")
print(f"Donor : {dos.ND} cm-3 at EV + {dos.ED} eV")
print(f"NV={dos.NV:10.4g} cm-3 DV0={dos.DV0}")
print(f"NC={dos.NC:10.4g} cm-3 DC0={dos.DC0}")
print(f" EF0={dos.EF0} eV")
print(f"mobility: {mu} cm2/Vs")
xEF = []
yNh = []
ySndeg = []
ySdeg = []
ySexact = []
print()
print("EF degpendence")
print(f"{'EF (eV)':>8} {'Nh (cm-3)':>10} {'S(ex) (uV/K)':>8} {'S(non-deg)':>10} {'S(deg)':>10} {'sigam (S/cm)':>10} {'mu_w':>8}")
nEF = 1001
EFstep = (0.5 - EFmin) / (nEF - 1)
nskip = int(nEF / 25 + 1.0e-4)
for i in range(0, nEF, nskip):
EF = EFmin + i * EFstep
Nh = dos.Nh(T, EF)
# Ne = dos.Ne(T, EF)
Sndeg = dos.cal_S_nondegenerated_from_Ne(n = Nh, rfac = r, charge = 1.0)
Sdeg = dos.cal_S_degenerated_from_Ne(T = T, n = Nh, rfac = r, charge = 1.0)
S = dos.cal_holeSeebeck(EF, T, rfac = r, unit = 'V/K')
sigma = e * Nh * mu
muw, nw, sign, carriertype = weighted_mobility(sigma * 100.0, S, T, unit = 'm')
xEF.append(EF)
yNh.append(Nh)
ySndeg.append(Sndeg)
ySdeg.append(Sdeg)
ySexact.append(S)
print(f"{EF:8.4f} eV {Nh:10.4g} {S*1e6:10.4g} {Sndeg*1e6:10.4g} {Sdeg*1e6:10.4g} {sigma:10.4g} {muw*1e4:8.4g}")
nskip = int(nSke / 25 + 1.0e-4)
xSke = []
yS = []
yfdeg = []
yfndeg = []
yEF = []
yN = []
ymu = []
ysigma = []
ymu = []
ySndeg2 = []
ySdeg2 = []
ySexact2 = []
ymuw2 = []
ymuw_new = []
ymuw_ex = []
print()
print(f"Transport properties at {T} K for mobility = {mu} cm2/Vs")
print(f"{'S/(kB/e)':>8} {'S (uV/K)':>8} {'EF (eV)':>8} {'fdeg':>8} {'fndeg':>8} {'N (cm-3)':>10} {'mu (cm2/Vs)':>8} {'sigma (S/cm)':>15}"
+ f" {'S(non-deg)':>12} {'S(deg)':>8} {'S(ex)':>8} {'muw(Snyder)':>15} {'muw(new)':>15} {'muw(exact)':>15}")
for i in range(1, nSke, nskip):
Ske = Skemin * exp(i * logSkestep)
S = Ske * kB / e # V/K
expS = exp(5.0 * (abs(Ske) - 1.0))
fdeg = 1.0 / (1.0 + expS)
fndeg = 1.0 / (1.0 + 1.0 / expS)
# EF = dos.EF_from_S(T, -abs(S), r, polarity = 'e', EFmin = EFmin, EFmax = EFmax, eps = eps, nmaxiter = nmaxiter, print_level = print_level)
EF = dos.EF_from_S(T, abs(S), r, polarity = 'h', EFmin = EFmin, EFmax = EFmax, eps = eps, nmaxiter = nmaxiter, print_level = print_level)
if EF is None:
continue
N = dos.Nh(T, EF)
# N = dos.Ne(T, EF)
Sndeg = dos.cal_S_nondegenerated_from_Ne(n = N, rfac = r, charge = 1.0)
Sdeg = dos.cal_S_degenerated_from_Ne(T = T, n = N, rfac = r, charge = 1.0)
Sexact = dos.cal_holeSeebeck(EF, T, rfac = r, unit = 'V/K')
sigma = e * N * mu
muw, nw, sign, carriertype = weighted_mobility(sigma * 100.0, Sexact, T, unit = 'm') # muw in m2/Vs
muw2, nw2, s2, ct2 = weighted_mobility_new(sigma * 100.0, S, T, r = r, unit = 'm')
muwe, nwe, s, ct, EF = weighted_mobility_exact(sigma * 100.0, Sexact, T, r = r, polarity = 'h',
EFmin = EFmin, EFmax = EFmax, eps = eps, nmaxiter = nmaxiter, print_level = print_level, unit = 'm')
xSke.append(Ske)
yS.append(S)
yfdeg.append(fdeg)
yfndeg.append(fndeg)
yEF.append(EF)
yN.append(N)
ymu.append(mu)
ysigma.append(sigma)
ySndeg2.append(Sndeg)
ySdeg2.append(Sdeg)
ySexact2.append(Sexact)
ymuw2.append(muw)
ymuw_new.append(muw2)
ymuw_ex.append(muwe)
print(f"{Ske:8.4f} {S*1e6:8.3g} {EF:8.3f} {fdeg:8.4f} {fndeg:8.4f} {N:10.4g} {mu:10.4g} {sigma:15.4g}"
+ f" {Sndeg*1e6:12.3g} {Sdeg*1e6:8.3g} {Sexact*1e6:8.3g} {muw*1e4:15.4g} {muw2*1e4:15.4g} {muwe*1e4:15.4g}")
outfile = 'weighted_mobility-out.xlsx'
print()
print(f"Save calculation results to [{outfile}]")
tkVariousData().to_excel(outfile,
labels = ['S/(kB/e)', 'S (V/K)', 'EF (eV)', 'fdeg', 'fndeg', 'N (cm-3)', 'mu (cm2/Vs)', 'sigma (S/cm)',
'S(non-deg)', 'S(deg)', 'S(ex)', 'mu_w(Snyder) (m2/Vs)', 'mu_w(new) (m2/Vs)', 'mu_w(exact) (m2/Vs)'],
data_list = [xSke, yS, yEF, yfdeg, yfndeg, yN, ymu, ysigma, ySndeg2, ySdeg2, ySexact2, ymuw2, ymuw_new, ymuw_ex])
#=============================
# Plot graphs
#=============================
fig, axes = plt.subplots(2, 1, figsize = figsize)
axf = axes[0]
axEF = axes[1]
axN = axes[0]
axf.plot(xSke, yfdeg, label = 'f(deg.)', color = 'black')
axf.plot(xSke, yfndeg, label = 'f(non-deg.)', color = 'blue')
axf.set_xscale('log')
axf.set_xlabel('S / (kB/e)', fontsize = fontsize)
axf.set_ylabel('f', fontsize = fontsize)
axf.tick_params(labelsize = fontsize)
axf.legend(fontsize = legend_fontsize)
axEF.plot(xEF, ySexact, label = 'S(exact)', color = 'black')
axEF.plot(xEF, ySdeg, label = 'S(deg.)', color = 'blue', linestyle = 'dashed')
axEF.plot(xEF, ySndeg, label = 'S(non-deg.)', color = 'darkgreen', linestyle = 'dashed')
# axEF.set_xscale('log')
axEF.set_yscale('log')
axEF.set_xlim([-1.0, None])
axEF.set_ylim([1.0e-5, max(ySexact) * 1.1])
axEF.set_xlabel('EF (eV)', fontsize = fontsize)
axEF.set_ylabel('S (V/K)', fontsize = fontsize)
axEF.tick_params(labelsize = fontsize)
axEF.legend(fontsize = legend_fontsize)
plt.tight_layout()
plt.pause(0.1)
print("")
app.terminate(pause = True)
[ドキュメント]
def exec_X():
"""
概要: パラメータXの依存性に対する重み付き移動度とキャリア濃度を計算します。
詳細説明: 入力ファイルからX、伝導率、ゼーベック係数のデータを読み込み、
指定された計算タイプ('Snyder', 'exact', 'approx')に基づいて
重み付き移動度とキャリア濃度を計算します。
結果は出力Excelファイルに保存され、Xに対する伝導率、ゼーベック係数、
重み付き移動度、キャリア濃度のグラフがプロットされます。
:returns: None
"""
print("")
print("input file :", infile)
print("output file:", outfile)
print("T = {} K".format(T0))
print(f"cal_type: {cal_type}")
print(f"m*: {meffDOS0} me")
print(f"r0: {r0}")
print("X_label :", T_label)
print("sigma_label:", sigma_label)
print("S_label :", S_label)
print("")
print("Read data from [{}]".format(infile))
datafile, labels, datalist = read_file(infile)
Xlabel, Xlist = datafile.FindDataArray(X_label, flag = 'i')
sigmalabel, sigmalist = datafile.FindDataArray(sigma_label, flag = 'i')
Slabel, Slist = datafile.FindDataArray(S_label, flag = 'i')
validate_data(Xlist, 'X data')
validate_data(sigmalist, 'sigma data')
validate_data(Slist, 'S data')
EV = 0.0
EC = 3.0
EFmin = EV - 2.0
EFmax = EC + 2.0
eps = 1.0e-10
nmaxiter = 1000
print_level = 0
muwlist = []
nwlist = []
ctlist = []
if cal_type == 'exact':
print(f"{Xlabel:12} {'EF(eV)':10} {sigmalabel:12} {Slabel:12} {'mu_w(cm^2/(Vs))':12} {'n_w(cm^-3)':12} {'type'}")
else:
print(f"{Xlabel:12} {sigmalabel:12} {Slabel:12} {'mu_w(cm^2/(Vs))':12} {'n_w(cm^-3)':12} {'type'}")
for ic in range(len(Xlist)):
if cal_type == 'Snyder':
mu_w, n_w, sign, carriertype = weighted_mobility(sigmalist[ic] * 100.0, Slist[ic], T0, unit = 'm')
elif cal_type == 'exact':
mu_w, n_w, sign, carriertype, EF = weighted_mobility_exact(sigmalist[ic] * 100.0, Slist[ic], T0, meff = meffDOS0, r = r0, polarity = 'h',
EFmin = EFmin, EFmax = EFmax, eps = eps, nmaxiter = nmaxiter, print_level = print_level, unit = 'm')
elif cal_type == 'approx':
mu_w, n_w, sign, carriertype = weighted_mobility_new (sigmalist[ic] * 100.0, Slist[ic], T0, meff = meffDOS0, r = r0, unit = 'm')
else:
app.terminate(f"\nError: calt_ype=[{cal_type}] is not supported.\n", pause = True)
mu_w *= 1.0e4
n_w *= 1.0e-6
muwlist.append(mu_w)
nwlist.append(n_w)
ctlist.append(carriertype)
if cal_type == 'exact':
print(f"{Xlist[ic]:12.6g} {EF:10.4g} {sigmalist[ic]:12.6g} {Slist[ic]:12.6g} {mu_w:12.6g} {n_w:12.6g} {carriertype}")
else:
print(f"{Xlist[ic]:12.6g} {sigmalist[ic]:12.6g} {Slist[ic]:12.6g} {mu_w:12.6g} {n_w:12.6g} {carriertype}")
print("")
print("Save results to [{}]".format(outfile))
tkVariousData().to_excel(outfile,
labels = [Xlabel, sigmalabel, Slabel, f"mu_w({cal_type})(cm^2/(Vs))", f"n_w({cal_type})(cm^-3)", 'type'],
data_list = [Xlist, sigmalist, Slist, muwlist, nwlist, ctlist])
#=============================
# Plot graphs
#=============================
fig = plt.figure(figsize = figsize)
ax1a = fig.add_subplot(1, 2, 1)
ax1b = ax1a.twinx()
ax2a = fig.add_subplot(1, 2, 2)
ax2b = ax2a.twinx()
xSp = []
xSm = []
Sp = []
Sm = []
for i in range(len(Xlist)):
if Slist[i] >= 0.0:
xSp.append(Xlist[i])
Sp.append(Slist[i])
else:
xSm.append(Xlist[i])
Sm.append(Slist[i])
xnp = []
xnm = []
np = []
nm = []
for i in range(len(Xlist)):
if ctlist[i] == 'h':
xnp.append(Xlist[i])
np.append(nwlist[i])
else:
xnm.append(Xlist[i])
nm.append(nwlist[i])
ins1 = ax1a.plot(Xlist, sigmalist, label = sigmalabel,
linestyle = '', marker = '^', markerfacecolor = 'black', markeredgecolor = 'black', markersize = markersize)
ins2 = ax1b.plot(xSp, Sp, label = "{} (h)".format(Slabel),
linestyle = '', marker = 'o', markerfacecolor = 'blue', markeredgecolor = 'blue', markersize = markersize)
ins3 = ax1b.plot(xSm, Sm, label = "{} (e)".format(Slabel),
linestyle = '', marker = 'o', markerfacecolor = 'red', markeredgecolor = 'red', markersize = markersize)
xrange = ax1b.get_xlim()
ax1b.plot(xrange, [0.0, 0.0], linestyle = 'dashed', color = 'red', linewidth = 0.5)
ax1a.set_yscale('log')
ax1a.set_xlabel(Xlabel, fontsize = fontsize)
ax1a.set_ylabel(sigmalabel, fontsize = fontsize)
ax1b.set_ylabel(Slabel, fontsize = fontsize)
ax1a.set_xlim(xrange)
ax1b.set_xlim(xrange)
ins = ins1 + ins2 + ins3
ax1a.legend(ins, [l.get_label() for l in ins], fontsize = legend_fontsize, loc = 'upper center') #loc = 'best')
# h1a, l1a = ax1a.get_legend_handles_labels()
# h1b, l1b = ax1b.get_legend_handles_labels()
# ax1a.legend(h1a + h1b, l1a + h1b, fontsize = legend_fontsize)
ax1a.set_title("{} (T = {} K)".format(infile, T0))
ax1a.tick_params(labelsize = fontsize)
ax1b.tick_params(labelsize = fontsize)
if cal_type == 'Snyder':
mu_label = f'$\mu_w$ ({cal_type})'
else:
mu_label = f'$\mu_w$ ({cal_type}, r={r0:.2f} m*={meffDOS0:.2f}me)'
ins1 = ax2a.plot(Xlist, muwlist, label = mu_label,
linestyle = '', marker = 'o', markerfacecolor = 'blue', markeredgecolor = 'blue', markersize = markersize)
ins2 = ax2b.plot(xnp, np, label = '$n_w$ (h)',
linestyle = '', marker = '^', markerfacecolor = 'blue', markeredgecolor = 'blue', markersize = markersize)
ins3 = ax2b.plot(xnm, nm, label = '$n_w$ (e)',
linestyle = '', marker = '^', markerfacecolor = 'white', markeredgecolor = 'red', markersize = markersize)
ax2b.plot(xrange, [0.0, 0.0], color = 'red', linestyle = 'dashed', linewidth = 0.5)
ax2b.set_yscale('log')
ax2a.set_xlabel(Xlabel, fontsize = fontsize)
ax2a.set_ylabel('$\mu_w$ (cm$^2$/(Vs))', fontsize = fontsize)
ax2b.set_ylabel('$n_w$ (cm$^{-3}$)', fontsize = fontsize)
ax2a.set_xlim(xrange)
ax2b.set_xlim(xrange)
ins = ins1 + ins2 + ins3
ax2b.legend(ins, [l.get_label() for l in ins], fontsize = legend_fontsize, loc = 'upper center') #loc = 'best')
# h2a, l2a = ax2a.get_legend_handles_labels() ins = ins1 + ins2
# h2b, l2b = ax2b.get_legend_handles_labels()
# ax2a.legend(h2a + h2b, l2a + h2b, fontsize = legend_fontsize)
ax2a.tick_params(labelsize = fontsize)
ax2b.tick_params(labelsize = fontsize)
# Rearange the graph axes so that they are not overlapped
plt.tight_layout()
plt.pause(0.1)
if cal_type == 'Snyder':
print()
print("#=====================================================")
print("# Warning: cal_type='Snyder' assumes r=0 and m*=1.0me.")
print("#=====================================================")
print()
app.terminate("", usage = usage, pause = True)
[ドキュメント]
def exec_T():
"""
概要: 温度依存性に対する重み付き移動度とキャリア濃度を計算します。
詳細説明: 入力ファイルから温度、伝導率、ゼーベック係数のデータを読み込み、
指定された計算タイプ('Snyder', 'exact', 'approx')に基づいて
重み付き移動度とキャリア濃度を計算します。
結果は出力Excelファイルに保存され、温度に対する伝導率、ゼーベック係数、
重み付き移動度、キャリア濃度のグラフがプロットされます。
:returns: None
"""
global X_label, T_label, sigma_label, S_label
print("")
print("input file :", infile)
print("output file:", outfile)
print(f"cal_type: {cal_type}")
print(f"m*: {meffDOS0} me")
print(f"r0: {r0}")
print("X_label :", T_label)
print("sigma_label:", sigma_label)
print("S_label :", S_label)
print("")
print("Read data from [{}]".format(infile))
datafile, labels, datalist = read_file(infile)
Tlabel, Tlist = datafile.FindDataArray(T_label, flag = 'i')
sigmalabel, sigmalist = datafile.FindDataArray(sigma_label, flag = 'i')
Slabel, Slist = datafile.FindDataArray(S_label, flag = 'i')
validate_data(Tlist, 'T data')
validate_data(sigmalist, 'sigma data')
validate_data(Slist, 'S data')
EV = 0.0
EC = 3.0
EFmin = EV - 2.0
EFmax = EC + 2.0
eps = 1.0e-10
nmaxiter = 1000
print_level = 0
muwlist = []
nwlist = []
ctlist = []
if cal_type == 'exact':
print(f"{Tlabel:12}\t{'EF(eV)':10} {sigmalabel:12} {Slabel:12} {'mu_w(cm^2/(Vs))':12} {'n_w(cm^-3)':12} {'type'}")
else:
print(f"{Tlabel:12} {sigmalabel:12} {Slabel:12}\t{'mu_w(cm^2/(Vs))':12} {'n_w(cm^-3)':12} {'type'}")
for ic in range(len(Tlist)):
if cal_type == 'Snyder':
mu_w, n_w, sign, carriertype = weighted_mobility(sigmalist[ic] * 100.0, Slist[ic], Tlist[ic], unit = 'm')
elif cal_type == 'exact':
mu_w, n_w, sign, carriertype, EF = weighted_mobility_exact(sigmalist[ic] * 100.0, Slist[ic], Tlist[ic], meff = meffDOS0, r = r0, polarity = 'h',
EFmin = EFmin, EFmax = EFmax, eps = eps, nmaxiter = nmaxiter, print_level = print_level, unit = 'm')
elif cal_type == 'approx':
mu_w, n_w, sign, carriertype = weighted_mobility_new (sigmalist[ic] * 100.0, Slist[ic], Tlist[ic], meff = meffDOS0, r = r0, unit = 'm')
else:
app.terminate(f"\nError: cal_type=[{cal_type}] is not supported.\n", pause = True)
mu_w *= 1.0e4
n_w *= 1.0e-6
muwlist.append(mu_w)
nwlist.append(n_w)
ctlist.append(carriertype)
if cal_type == 'exact':
print(f"{Tlist[ic]:12.6g} {EF:10.4g} {sigmalist[ic]:12.6g} {Slist[ic]:12.6g} {mu_w:12.6g} {n_w:12.6g} {carriertype}")
else:
print(f"{Tlist[ic]:12.6g} {sigmalist[ic]:12.6g} {Slist[ic]:12.6g} {mu_w:12.6g} {n_w:12.6g} {carriertype}")
print("")
print("Save results to [{}]".format(outfile))
tkVariousData().to_excel(outfile,
labels = [Tlabel, sigmalabel, Slabel, f"mu_w({cal_type},cm^2/(Vs))", f"n_w({cal_type},cm^-3)", 'type'],
data_list = [Tlist, sigmalist, Slist, muwlist, nwlist, ctlist])
#=============================
# Plot graphs
#=============================
fig = plt.figure(figsize = figsize)
ax1a = fig.add_subplot(1, 2, 1)
ax1b = ax1a.twinx()
ax2a = fig.add_subplot(1, 2, 2)
ax2b = ax2a.twinx()
xSp = []
xSm = []
Sp = []
Sm = []
for i in range(len(Tlist)):
if Slist[i] >= 0.0:
xSp.append(Tlist[i])
Sp.append(Slist[i])
else:
xSm.append(Tlist[i])
Sm.append(Slist[i])
xnp = []
xnm = []
np = []
nm = []
for i in range(len(Tlist)):
if ctlist[i] == 'h':
xnp.append(Tlist[i])
np.append(nwlist[i])
else:
xnm.append(Tlist[i])
nm.append(nwlist[i])
ins1 = ax1a.plot(Tlist, sigmalist, label = sigmalabel,
linestyle = '', marker = '^', markerfacecolor = 'black', markeredgecolor = 'black', markersize = markersize)
ins2 = ax1b.plot(xSp, Sp, label = "{} (h)".format(Slabel),
linestyle = '', marker = 'o', markerfacecolor = 'blue', markeredgecolor = 'blue', markersize = markersize)
ins3 = ax1b.plot(xSm, Sm, label = "{} (e)".format(Slabel),
linestyle = '', marker = 'o', markerfacecolor = 'white', markeredgecolor = 'blue', markersize = markersize)
xrange = ax1b.get_xlim()
ax1b.plot(xrange, [0.0, 0.0], linestyle = 'dashed', color = 'red', linewidth = 0.5)
ax1a.set_yscale('log')
ax1a.set_xlabel(Tlabel, fontsize = fontsize)
ax1a.set_ylabel(sigmalabel, fontsize = fontsize)
ax1b.set_ylabel(Slabel, fontsize = fontsize)
ax1a.set_xlim(xrange)
ax1b.set_xlim(xrange)
ins = ins1 + ins2 + ins3
ax1a.legend(ins, [l.get_label() for l in ins], fontsize = legend_fontsize, loc = 'upper center') #loc = 'best')
# h1a, l1a = ax1a.get_legend_handles_labels()
# h1b, l1b = ax1b.get_legend_handles_labels()
# ax1a.legend(h1a + h1b, l1a + h1b, fontsize = legend_fontsize)
ax1a.set_title("{} (T = {} K)".format(infile, T0))
ax1a.tick_params(labelsize = fontsize)
ax1b.tick_params(labelsize = fontsize)
if cal_type == 'Snyder':
mu_label = f'$\mu_w$ ({cal_type})'
else:
mu_label = f'$\mu_w$ ({cal_type}, r={r0:.2f} m*={meffDOS0:.2f}me)'
ins1 = ax2a.plot(Tlist, muwlist, label = mu_label,
linestyle = '', marker = 'o', markerfacecolor = 'blue', markeredgecolor = 'blue', markersize = markersize)
ins2 = ax2b.plot(xnp, np, label = '$n_w$ (h)',
linestyle = '', marker = '^', markerfacecolor = 'white', markeredgecolor = 'blue', markersize = markersize)
ins3 = ax2b.plot(xnm, nm, label = '$n_w$ (e)',
linestyle = '', marker = '^', markerfacecolor = 'white', markeredgecolor = 'red', markersize = markersize)
ax2b.plot(xrange, [0.0, 0.0], color = 'red', linestyle = 'dashed', linewidth = 0.5)
ax2b.set_yscale('log')
ax2a.set_xlabel(Tlabel, fontsize = fontsize)
ax2a.set_ylabel('$\mu_w$ (cm$^2$/(Vs))', fontsize = fontsize)
ax2b.set_ylabel('$n_w$ (cm$^{-3}$)', fontsize = fontsize)
ax2a.set_xlim(xrange)
ax2b.set_xlim(xrange)
ins = ins1 + ins2 + ins3
ax2a.legend(ins, [l.get_label() for l in ins], fontsize = legend_fontsize, loc = 'upper center') #loc = 'best')
# h2a, l2a = ax2a.get_legend_handles_labels()
# h2b, l2b = ax2b.get_legend_handles_labels()
# ax2a.legend(h2a + h2b, l2a + h2b, fontsize = legend_fontsize)
ax2a.tick_params(labelsize = fontsize)
ax2b.tick_params(labelsize = fontsize)
# Rearange the graph axes so that they are not overlapped
plt.tight_layout()
plt.pause(0.1)
if cal_type == 'Snyder':
print()
print("#=====================================================")
print("# Warning: cal_type='Snyder' assumes r=0 and m*=1.0me.")
print("#=====================================================")
print()
app.terminate("", usage = usage, pause = True)
[ドキュメント]
def main():
"""
概要: スクリプトのメインエントリポイントです。
詳細説明: `tkApplication` を初期化し、コマンドライン引数からグローバル変数を更新します。
`mode` 変数の値に応じて、`exec_check`、`exec_single`、`exec_X`、`exec_T` のいずれかの計算関数を呼び出します。
無効なモードが指定された場合は、エラーメッセージを表示してアプリケーションを終了します。
:returns: None
"""
global app
app = tkApplication()
# logfile = app.replace_path(infile)
# print(f"Open logfile [{logfile}]")
# app.redirect(targets = ["stdout", logfile], mode = 'w')
print("")
print("=============================================================")
print("Calculate weighted mobility and carrier concentration ")
print("from conductivity (S/cm) and Seebeck coefficient (V/K)")
print("=============================================================")
print("")
updatevars()
print("mode:", mode)
if mode == 'check':
exec_check()
elif mode == 'single':
exec_single()
elif mode == 'X':
exec_X()
elif mode == 'T':
exec_T()
else:
app.terminate("Error: Invalid mode [{}]".format(mode), usage = usage, pause = True)
if (__name__ == '__main__'):
main()