"""
This script calculates the weighted mobility and performs various calculations related to it.
It includes functions for checking results, single point calculation, T-/X-dependences of weighted mobility, and reading data from a file.
The script also defines physical constants and parameters used in the calculations.
"""
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
# Rest of the code...
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
# Rest of the code...
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; # C2N-1m-2";
kB = 1.380658e-23 # JK-1";
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):
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):
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():
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):
"""
Read data from a file.
Args:
fname (str): The name of the file to read.
Returns:
tuple: A tuple containing the datafile object, labels, and datalist.
"""
print("")
datafile = tkVariousData(infile)
labels, datalist = datafile.Read_minimum_matrix(close_fp=True, usage=usage)
return datafile, labels, datalist
def validate_data(list, desc):
"""
Validate the given data list.
Parameters:
list (list): The data list to be validated.
desc (str): Description of the data list.
Raises:
terminate: If the data list is None.
Returns:
None
"""
if list is None:
app.terminate(f"\nError in validate_data: Null data for {desc}\n", pause=True)
def validate_data(list, desc):
if list is None:
app.terminate(f"\nError in validate_data: Null data for {desc}\n", pause = True)
def exec_single():
"""
Executes a single calculation of weighted mobility.
This function calculates the weighted mobility using the provided parameters:
- sigma0: conductivity in S/cm
- S0: Seebeck coefficient in V/K
- T0: temperature in K
The function prints the calculated values of weighted mobility (mu_w), carrier concentration (n_w),
and the majority carrier type.
Example usage:
exec_single()
"""
'''
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():
"""
Check weighted mobility results.
This function calculates and prints various properties related to weighted mobility.
It performs calculations for different equations of weighted mobility and carrier density,
and saves the results to an Excel file.
Additionally, it plots two graphs showing the dependence of f on Ske and the dependence of S on EF.
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():
"""
Executes calculation of weighted mobility with respect to a parameter X
This function reads data from an Excel file, performs calculations, and saves the results to another file.
It also plots graphs based on the calculated data.
Parameters:
None
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} {'mu_w(ex,cm^2/(Vs))':12} {'n_w(ex,cm^-3)':12} {'type'}")
else:
print(f"{Xlabel:12} {sigmalabel:12} {Slabel:12} {'mu_w(cm^2/(Vs))':12} {'n_w(cm^-3)':12} {'mu_w(ex,cm^2/(Vs))':12} {'n_w(ex,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,
[Xlabel, sigmalabel, Slabel, f"mu_w({cal_type})(cm^2/(Vs))", f"n_w({cal_type})(cm^-3)", 'type'],
[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():
"""
Execute the main function for calculating weighted mobility as a function of temperature.
This function reads data from an input Excel file, performs calculations for weighted mobility,
and saves the results to an output file. It also plots graphs of the calculated values.
Parameters:
None
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,
[Tlabel, sigmalabel, Slabel, f"mu_w({cal_type},cm^2/(Vs))", f"n_w({cal_type},cm^-3)", 'type'],
[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():
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()