Files
Dean Huang e9bd61b56f start
2025-12-08 10:11:12 +08:00

337 lines
16 KiB
Python

# Copyright 2013 DEVSIM LLC
#
# SPDX-License-Identifier: Apache-2.0
from devsim import set_parameter
from devsim.python_packages.model_create import (
CreateNodeModel,
CreateNodeModelDerivative,
CreateEdgeModel,
CreateElementModel2d,
CreateElementModelDerivative2d,
CreateGeometricMean,
CreateGeometricMeanDerivative,
)
def Set_Mobility_Parameters(device, region):
# As
set_parameter(device=device, region=region, name="mu_min_e", value=52.2)
set_parameter(device=device, region=region, name="mu_max_e", value=1417)
set_parameter(device=device, region=region, name="theta1_e", value=2.285)
set_parameter(device=device, region=region, name="m_e", value=1.0)
set_parameter(device=device, region=region, name="f_BH", value=3.828)
set_parameter(device=device, region=region, name="f_CW", value=2.459)
set_parameter(device=device, region=region, name="c_D", value=0.21)
set_parameter(device=device, region=region, name="Nref_D", value=4.0e20)
set_parameter(device=device, region=region, name="Nref_1_e", value=9.68e16)
set_parameter(device=device, region=region, name="alpha_1_e", value=0.68)
# B
set_parameter(device=device, region=region, name="mu_min_h", value=44.9)
set_parameter(device=device, region=region, name="mu_max_h", value=470.5)
set_parameter(device=device, region=region, name="theta1_h", value=2.247)
set_parameter(device=device, region=region, name="m_h", value=1.258)
set_parameter(device=device, region=region, name="c_A", value=0.50)
set_parameter(device=device, region=region, name="Nref_A", value=7.2e20)
set_parameter(device=device, region=region, name="Nref_1_h", value=2.2e17)
set_parameter(device=device, region=region, name="alpha_1_h", value=0.719)
# F_Pe F_Ph equations
set_parameter(device=device, region=region, name="r1", value=0.7643)
set_parameter(device=device, region=region, name="r2", value=2.2999)
set_parameter(device=device, region=region, name="r3", value=6.5502)
set_parameter(device=device, region=region, name="r4", value=2.3670)
set_parameter(device=device, region=region, name="r5", value=-0.01552)
set_parameter(device=device, region=region, name="r6", value=0.6478)
# G_Pe G_Ph equations
set_parameter(device=device, region=region, name="s1", value=0.892333)
set_parameter(device=device, region=region, name="s2", value=0.41372)
set_parameter(device=device, region=region, name="s3", value=0.19778)
set_parameter(device=device, region=region, name="s4", value=0.28227)
set_parameter(device=device, region=region, name="s5", value=0.005978)
set_parameter(device=device, region=region, name="s6", value=1.80618)
set_parameter(device=device, region=region, name="s7", value=0.72169)
# velocity saturation
set_parameter(device=device, region=region, name="vsat_e", value=1.0e7)
set_parameter(device=device, region=region, name="vsat_h", value=1.0e7)
# Lucent Mobility
set_parameter(device=device, region=region, name="alpha_e", value=6.85e-21)
set_parameter(device=device, region=region, name="alpha_h", value=7.82e-21)
set_parameter(device=device, region=region, name="A_e", value=2.58)
set_parameter(device=device, region=region, name="A_h", value=2.18)
set_parameter(device=device, region=region, name="B_e", value=3.61e7)
set_parameter(device=device, region=region, name="B_h", value=1.51e7)
set_parameter(device=device, region=region, name="C_e", value=1.70e4)
set_parameter(device=device, region=region, name="C_h", value=4.18e3)
set_parameter(device=device, region=region, name="kappa_e", value=1.7)
set_parameter(device=device, region=region, name="kappa_h", value=0.9)
set_parameter(device=device, region=region, name="tau_e", value=0.0233)
set_parameter(device=device, region=region, name="tau_h", value=0.0119)
set_parameter(device=device, region=region, name="eta_e", value=0.0767)
set_parameter(device=device, region=region, name="eta_h", value=0.123)
set_parameter(device=device, region=region, name="delta_e", value=3.58e18)
set_parameter(device=device, region=region, name="delta_h", value=4.10e15)
# mobility_h="(Electrons@n0*Electrons@n1)^(0.5)"
# mobility_e="(Holes@n0*Holes@n1)^(0.5)"
# assumption is we will substitute As or P as appropriate
# remember the derivatives as well
### This is the Klaassen mobility, need to adapt to Darwish
def Klaassen_Mobility(device, region):
# require Electrons, Holes, Donors, Acceptors already exist
mu_L_e = "(mu_max_e * (300 / T)^theta1_e)"
mu_L_h = "(mu_max_h * (300 / T)^theta1_h)"
CreateNodeModel(device, region, "mu_L_e", mu_L_e)
CreateNodeModel(device, region, "mu_L_h", mu_L_h)
mu_e_N = (
"(mu_max_e * mu_max_e / (mu_max_e - mu_min_e) * (T/300)^(3*alpha_1_e - 1.5))"
)
mu_h_N = (
"(mu_max_h * mu_max_h / (mu_max_h - mu_min_h) * (T/300)^(3*alpha_1_h - 1.5))"
)
CreateNodeModel(device, region, "mu_e_N", mu_e_N)
CreateNodeModel(device, region, "mu_h_N", mu_h_N)
mu_e_c = "(mu_min_e * mu_max_e / (mu_max_e - mu_min_e)) * (300/T)^(0.5)"
mu_h_c = "(mu_min_h * mu_max_h / (mu_max_h - mu_min_h)) * (300/T)^(0.5)"
CreateNodeModel(device, region, "mu_e_c", mu_e_c)
CreateNodeModel(device, region, "mu_h_c", mu_h_c)
PBH_e = "(1.36e20/(Electrons + Holes) * (m_e) * (T/300)^2)"
PBH_h = "(1.36e20/(Electrons + Holes) * (m_h) * (T/300)^2)"
CreateNodeModel(device, region, "PBH_e", PBH_e)
CreateNodeModelDerivative(device, region, "PBH_e", PBH_e, "Electrons", "Holes")
CreateNodeModel(device, region, "PBH_h", PBH_h)
CreateNodeModelDerivative(device, region, "PBH_h", PBH_h, "Electrons", "Holes")
Z_D = "(1 + 1 / (c_D + (Nref_D / Donors)^2))"
Z_A = "(1 + 1 / (c_A + (Nref_A / Acceptors)^2))"
CreateNodeModel(device, region, "Z_D", Z_D)
CreateNodeModel(device, region, "Z_A", Z_A)
N_D = "(Z_D * Donors)"
N_A = "(Z_A * Acceptors)"
CreateNodeModel(device, region, "N_D", N_D)
CreateNodeModel(device, region, "N_A", N_A)
N_e_sc = "(N_D + N_A + Holes)"
N_h_sc = "(N_A + N_D + Electrons)"
CreateNodeModel(device, region, "N_e_sc", N_e_sc)
CreateNodeModelDerivative(device, region, "N_e_sc", N_e_sc, "Electrons", "Holes")
CreateNodeModel(device, region, "N_h_sc", N_h_sc)
CreateNodeModelDerivative(device, region, "N_h_sc", N_h_sc, "Electrons", "Holes")
PCW_e = "(3.97e13 * (1/(Z_D^3 * N_e_sc) * (T/300)^3)^(2/3))"
PCW_h = "(3.97e13 * (1/(Z_A^3 * N_h_sc) * (T/300)^3)^(2/3))"
CreateNodeModel(device, region, "PCW_e", PCW_e)
CreateNodeModelDerivative(device, region, "PCW_e", PCW_e, "Electrons", "Holes")
CreateNodeModel(device, region, "PCW_h", PCW_h)
CreateNodeModelDerivative(device, region, "PCW_h", PCW_h, "Electrons", "Holes")
Pe = "(1/(f_CW / PCW_e + f_BH/PBH_e))"
Ph = "(1/(f_CW / PCW_h + f_BH/PBH_h))"
CreateNodeModel(device, region, "Pe", Pe)
CreateNodeModelDerivative(device, region, "Pe", Pe, "Electrons", "Holes")
CreateNodeModel(device, region, "Ph", Ph)
CreateNodeModelDerivative(device, region, "Ph", Ph, "Electrons", "Holes")
G_Pe = (
"(1 - s1 / (s2 + (1.0/m_e * T/300)^s4 * Pe)^s3 + s5/((m_e * 300/T)^s7*Pe)^s6)"
)
G_Ph = (
"(1 - s1 / (s2 + (1.0/m_h * T/300)^s4 * Ph)^s3 + s5/((m_h * 300/T)^s7*Ph)^s6)"
)
CreateNodeModel(device, region, "G_Pe", G_Pe)
CreateNodeModelDerivative(device, region, "G_Pe", G_Pe, "Electrons", "Holes")
CreateNodeModel(device, region, "G_Ph", G_Ph)
CreateNodeModelDerivative(device, region, "G_Ph", G_Ph, "Electrons", "Holes")
F_Pe = "((r1 * Pe^r6 + r2 + r3 * m_e/m_h)/(Pe^r6 + r4 + r5 * m_e/m_h))"
F_Ph = "((r1 * Ph^r6 + r2 + r3 * m_h/m_e)/(Ph^r6 + r4 + r5 * m_h/m_e))"
CreateNodeModel(device, region, "F_Pe", F_Pe)
CreateNodeModelDerivative(device, region, "F_Pe", F_Pe, "Electrons", "Holes")
CreateNodeModel(device, region, "F_Ph", F_Ph)
CreateNodeModelDerivative(device, region, "F_Ph", F_Ph, "Electrons", "Holes")
N_e_sc_eff = "(N_D + G_Pe * N_A + Holes / F_Pe)"
N_h_sc_eff = "(N_A + G_Ph * N_D + Electrons / F_Ph)"
CreateNodeModel(device, region, "N_e_sc_eff", N_e_sc_eff)
CreateNodeModelDerivative(
device, region, "N_e_sc_eff", N_e_sc_eff, "Electrons", "Holes"
)
CreateNodeModel(device, region, "N_h_sc_eff", N_h_sc_eff)
CreateNodeModelDerivative(
device, region, "N_h_sc_eff", N_h_sc_eff, "Electrons", "Holes"
)
mu_e_D_A_h = "mu_e_N * N_e_sc/N_e_sc_eff * (Nref_1_e / N_e_sc)^alpha_1_e + mu_e_c * ((Electrons + Holes)/N_e_sc_eff)"
mu_h_D_A_e = "mu_h_N * N_h_sc/N_h_sc_eff * (Nref_1_h / N_h_sc)^alpha_1_h + mu_h_c * ((Electrons + Holes)/N_h_sc_eff)"
CreateNodeModel(device, region, "mu_e_D_A_h", mu_e_D_A_h)
CreateNodeModelDerivative(
device, region, "mu_e_D_A_h", mu_e_D_A_h, "Electrons", "Holes"
)
CreateNodeModel(device, region, "mu_h_D_A_e", mu_h_D_A_e)
CreateNodeModelDerivative(
device, region, "mu_h_D_A_e", mu_h_D_A_e, "Electrons", "Holes"
)
mu_bulk_e_Node = "mu_e_D_A_h * mu_L_e / (mu_e_D_A_h + mu_L_e)"
CreateNodeModel(device, region, "mu_bulk_e_Node", mu_bulk_e_Node)
CreateNodeModelDerivative(
device, region, "mu_bulk_e_Node", mu_bulk_e_Node, "Electrons", "Holes"
)
mu_bulk_h_Node = "mu_h_D_A_e * mu_L_h / (mu_h_D_A_e + mu_L_h)"
CreateNodeModel(device, region, "mu_bulk_h_Node", mu_bulk_h_Node)
CreateNodeModelDerivative(
device, region, "mu_bulk_h_Node", mu_bulk_h_Node, "Electrons", "Holes"
)
CreateGeometricMean(device, region, "mu_bulk_e_Node", "mu_bulk_e")
CreateGeometricMeanDerivative(
device, region, "mu_bulk_e_Node", "mu_bulk_e", "Electrons", "Holes"
)
CreateGeometricMean(device, region, "mu_bulk_h_Node", "mu_bulk_h")
CreateGeometricMeanDerivative(
device, region, "mu_bulk_h_Node", "mu_bulk_h", "Electrons", "Holes"
)
# mu_bulk is the original bulk model on the edge
# mu_sat is the saturation velocity model name
# vsat is the name of the parameter for velocity saturation
# eparallel is the name of the parallel efield model
def Philips_VelocitySaturation(device, region, mu_sat, mu_bulk, eparallel, vsat):
mu = "2*({mu_bulk}) / (1 + (1 + 4 * (max(0, ({mu_bulk}) * {eparallel})/{vsat})^2)^0.5)".format(
mu_bulk=mu_bulk, eparallel=eparallel, vsat=vsat
)
CreateElementModel2d(device, region, mu_sat, mu)
CreateElementModelDerivative2d(
device, region, mu_sat, mu, "Potential", "Electrons", "Holes"
)
#### Later on need model for temperature on edge
#### Assumption is Enormal is a magnitude
def Philips_Surface_Mobility(device, region, enormal_e, enormal_h):
#### for now, we assume that temperature is an edge quantity and not variable dependent
T_prime_e = "(T/300)^kappa_e"
T_prime_h = "(T/300)^kappa_h"
CreateEdgeModel(device, region, "T_prime_e", T_prime_e)
CreateEdgeModel(device, region, "T_prime_h", T_prime_h)
# no variables, only parameters
CreateNodeModel(device, region, "NI_node", "(N_D + N_A)")
CreateGeometricMean(device, region, "NI_node", "NI")
# CreateGeometricMean(device, region, "Electrons", edgeElectrons)
# CreateGeometricMeanDerivative(device, region, "Electrons", edgeElectrons Electrons)
# CreateGeometricMean(device, region, "Holes", edgeHoles)
# CreateGeometricMeanDerivative(device, region, "Holes", edgeHoles Holes)
#### Need to prevent ridiculus mobilities for small Enormal
mu_ac_e = (
"B_e /max({0},1e2) + (C_e * NI^tau_e * max({0},1e2)^(-1/3)) / T_prime_e".format(
enormal_e
)
)
mu_ac_h = (
"B_h /max({0},1e2) + (C_h * NI^tau_h * max({0},1e2)^(-1/3)) / T_prime_h".format(
enormal_h
)
)
CreateElementModel2d(device, region, "mu_ac_e", mu_ac_e)
CreateElementModelDerivative2d(device, region, "mu_ac_e", mu_ac_e, "Potential")
CreateElementModel2d(device, region, "mu_ac_h", mu_ac_h)
CreateElementModelDerivative2d(device, region, "mu_ac_h", mu_ac_h, "Potential")
# gamma_e="A_e + alpha_e * (edgeElectrons + edgeHoles) * NI^(-eta_e)"
# gamma_h="A_h + alpha_h * (edgeElectrons + edgeHoles) * NI^(-eta_h)"
# CreateElementModel2d (device, region, "gamma_e", gamma_e)
# CreateElementModelDerivative2d(device, region, "gamma_e", gamma_e Potential Electrons Holes)
# CreateElementModel2d (device, region, "gamma_h", gamma_h)
# CreateElementModelDerivative2d(device, region, "gamma_h", gamma_h Potential Electrons Holes)
# Hopefully a less problematic formulation
gamma_e = "A_e + alpha_e * (Electrons + Holes) * NI_node^(-eta_e)"
gamma_h = "A_h + alpha_h * (Electrons + Holes) * NI_node^(-eta_h)"
CreateNodeModel(device, region, "gamma_e_Node", gamma_e)
CreateNodeModelDerivative(
device, region, "gamma_e_Node", gamma_e, "Electrons", "Holes"
)
CreateGeometricMean(device, region, "gamma_e_Node", "gamma_e")
CreateGeometricMeanDerivative(
device, region, "gamma_e_Node", "gamma_e", "Electrons", "Holes"
)
CreateNodeModel(device, region, "gamma_h_Node", gamma_h)
CreateNodeModelDerivative(
device, region, "gamma_h_Node", gamma_h, "Electrons", "Holes"
)
CreateGeometricMean(device, region, "gamma_h_Node", "gamma_h")
CreateGeometricMeanDerivative(
device, region, "gamma_h_Node", "gamma_h", "Electrons", "Holes"
)
#### Need to prevent ridiculus mobilities for small Enormal
mu_sr_e = "delta_e *(max({0},1e2))^(-gamma_e)".format(enormal_e)
mu_sr_h = "delta_h *(max({0},1e2))^(-gamma_h)".format(enormal_h)
# mu_sr_e="1e8"
# mu_sr_h="1e8"
CreateElementModel2d(device, region, "mu_sr_e", mu_sr_e)
CreateElementModelDerivative2d(
device, region, "mu_sr_e", mu_sr_e, "Potential", "Electrons", "Holes"
)
CreateElementModel2d(device, region, "mu_sr_h", mu_sr_h)
CreateElementModelDerivative2d(
device, region, "mu_sr_h", mu_sr_h, "Potential", "Electrons", "Holes"
)
mu_e_0 = "mu_bulk_e * mu_ac_e * mu_sr_e / (mu_bulk_e*mu_ac_e + mu_bulk_e*mu_sr_e + mu_ac_e*mu_sr_e)"
mu_h_0 = "mu_bulk_h * mu_ac_h * mu_sr_h / (mu_bulk_h*mu_ac_h + mu_bulk_h*mu_sr_h + mu_ac_h*mu_sr_h)"
CreateElementModel2d(device, region, "mu_e_0", mu_e_0)
CreateElementModel2d(device, region, "mu_h_0", mu_h_0)
#### complicated derivation here
for k in ("e", "h"):
for i in ("Potential", "Electrons", "Holes"):
for j in ("@en0", "@en1", "@en2"):
ex = "mu_{k}_0^2 * (mu_bulk_{k}^(-2)*mu_bulk_{k}:{i}{j} + mu_ac_{k}^(-2)*mu_ac_{k}:{i}{j} + mu_sr_{k}^(-2) * mu_sr_{k}:{i}{j})".format(
i=i, j=j, k=k
)
CreateElementModel2d(
device, region, "mu_{k}_0:{i}{j}".format(i=i, j=j, k=k), ex
)
# CreateElementModelDerivative2d(device, region, "mu_e_0", mu_sr_e Potential Electrons Holes)
# CreateElementModelDerivative2d(device, region, "mu_h_0", mu_sr_h Potential Electrons Holes)
#### do we need to consider what happens if the j dot e in wrong direction
#### or do we take care of this before
# mu_e_ph="2*mu_e_0 / ((1 + (1 + 4 * (mu_e_0 * eparallel_e)^2))^(0.5))"
# mu_h_ph="2*mu_h_0 / ((1 + (1 + 4 * (mu_h_0 * eparallel_h)^2))^(0.5))"
### do geometric mean so that
# emobility = sqrt(mobility@n0 * mobility@n1)
# emobility:mobility@n0 = emobility/mobility@n0
# emobility:mobility@n1 = emobility/mobility@n1
# The @n0 means the quantity mobility:Electrons @n0, not the derivative of an node quantity by an edge quantitiy
# emobility:Electrons@n0 = emobility:mobility@n0 * mobility:Electrons@n0
# emobility:Electrons@n1 = emobility:mobility@n1 * mobility:Electrons@n1