# 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