def createSiliconDriftDiffusionAtContact(device, region, contact): format_dict = {"contact": contact} for name, equation in ( ("%(contact)snodeelectrons", "ifelse(NetDoping > 0, Electrons - celec_%(contact)s, Electrons - n_i^2/chole_%(contact)s)" ), ("%(contact)snodeholes", "ifelse(NetDoping < 0, Holes - chole_%(contact)s, Holes - n_i^2/celec_%(contact)s)" ), ("%(contact)snodeelectrons:Electrons", "1.0"), ("%(contact)snodeholes:Holes", "1.0"), ): name_sub = name % format_dict equation_sub = equation % format_dict devsim.contact_node_model(device=device, contact=contact, name=name_sub, equation=equation_sub) devsim.contact_equation(device=device, contact=contact, name="ElectronContinuityEquation", variable_name="Electrons", node_model="%snodeelectrons" % contact, edge_current_model="ElectronCurrent") devsim.contact_equation(device=device, contact=contact, name="HoleContinuityEquation", variable_name="Holes", node_model="%snodeholes" % contact, edge_current_model="HoleCurrent")
def createSiliconPotentialOnlyContact(device, region, contact): bias_name = "%sbias" % contact format_dict = {"contact": contact} devsim.set_parameter(device=device, region=region, name=bias_name, value=0.0) for name, equation in ( ("celec_%(contact)s", "1e-10 + 0.5*abs(NetDoping+(NetDoping^2 + 4 * n_i^2)^(0.5))"), ("chole_%(contact)s", "1e-10 + 0.5*abs(-NetDoping+(NetDoping^2 + 4 * n_i^2)^(0.5))"), ("%(contact)snodemodel", ''' ifelse(NetDoping > 0, Potential-%(contact)sbias-V_t*log(celec_%(contact)s/n_i), Potential-%(contact)sbias+V_t*log(chole_%(contact)s/n_i))'''), ("%(contact)snodemodel:Potential", "1"), ): name_sub = name % format_dict equation_sub = equation % format_dict devsim.contact_node_model(device=device, contact=contact, name=name_sub, equation=equation_sub) devsim.contact_equation(device=device, contact=contact, name="PotentialEquation", variable_name="Potential", node_model="%snodemodel" % contact)
def setup_dg_contact(device, contact, eq_name, v_name): #TODO: test if these models already exist on the region m = eq_name + '_' + contact CreateContactNodeModel(device, contact, m, v_name) d = m + ':' + v_name CreateContactNodeModel(device, contact, d, '1') ds.contact_equation(device=device, contact=contact, name=eq_name, node_model=m)
def CreateSiliconPotentialOnlyContact(device, region, contact, is_circuit=False): ''' Creates the potential equation at the contact if is_circuit is true, than use node given by GetContactBiasName ''' if not InNodeModelList(device, region, "contactcharge_node"): CreateNodeModel(device, region, "contactcharge_node", "q*IntrinsicCharge") celec_model = "(1e-10 + 0.5*abs(NetDoping+(NetDoping^2 + 4 * NIE^2)^(0.5)))" chole_model = "(1e-10 + 0.5*abs(-NetDoping+(NetDoping^2 + 4 * NIE^2)^(0.5)))" contact_model = "Potential -{0} + ifelse(NetDoping > 0, \ -V_t*log({1}/NIE), \ V_t*log({2}/NIE))".format(GetContactBiasName(contact), celec_model, chole_model) contact_model_name = GetContactNodeModelName(contact) CreateContactNodeModel(device, contact, contact_model_name, contact_model) CreateContactNodeModel(device, contact, "{0}:{1}".format(contact_model_name, "Potential"), "1") if is_circuit: CreateContactNodeModel( device, contact, "{0}:{1}".format(contact_model_name, GetContactBiasName(contact)), "-1") if is_circuit: ds.contact_equation(device=device, contact=contact, name="PotentialEquation", node_model=contact_model_name, edge_model="", node_charge_model="contactcharge_node", edge_charge_model="DField", node_current_model="", edge_current_model="", circuit_node=GetContactBiasName(contact)) else: ds.contact_equation(device=device, contact=contact, name="PotentialEquation", node_model=contact_model_name, edge_model="", node_charge_model="contactcharge_node", edge_charge_model="DField", node_current_model="", edge_current_model="")
def SetupInitialResistorContact(device, contact, use_circuit_bias=False, circuit_node=""): if circuit_node: bias_name = circuit_node else: bias_name = contact + "bias" bias_node_model = contact + "node_model" devsim.contact_node_model(device=device, contact=contact, name=bias_node_model, equation="Potential - %s" % bias_name) devsim.contact_node_model(device=device, contact=contact, name="%s:Potential" % bias_node_model, equation="1") if use_circuit_bias: devsim.contact_node_model(device=device, contact=contact, name="%s:%s" % (bias_node_model, bias_name), equation="-1") #edge_model -device $device -region $region -name "contactcharge_edge_top" -equation $conteq if use_circuit_bias: devsim.contact_equation(device=device, contact=contact, name="PotentialEquation", variable_name="Potential", node_model=bias_node_model, circuit_node=bias_name) else: devsim.contact_equation(device=device, contact=contact, name="PotentialEquation", variable_name="Potential", node_model=bias_node_model)
def SetupCarrierResistorContact(device, contact, use_circuit_bias=False, circuit_node=""): ''' Electron continuity equation at contact ''' if circuit_node: bias_name = circuit_node else: bias_name = contact + "bias" region = devsim.get_region_list(device=device, contact=contact)[0] if 'celec' not in devsim.get_node_model_list(device=device, region=region): devsim.node_model( device=device, region=region, name="celec", equation= "0.5*(NetDoping+(NetDoping^2 + 4 * IntrinsicDensity^2)^(0.5))") for name, equation in ( ("%snodeelectrons" % contact, "Electrons - celec"), ("%snodeelectrons:Electrons" % contact, "1."), ): devsim.contact_node_model(device=device, contact=contact, name=name, equation=equation) if use_circuit_bias: devsim.contact_equation(device=device, contact=contact, name="ElectronContinuityEquation", variable_name="Electrons", node_model="%snodeelectrons" % contact, edge_current_model="ElectronCurrent", circuit_node=bias_name) else: devsim.contact_equation(device=device, contact=contact, name="ElectronContinuityEquation", variable_name="Electrons", node_model="%snodeelectrons" % contact, edge_current_model="ElectronCurrent")
def CreateOxideContact(device, region, contact): conteq = "Permittivity*EField" contact_bias_name = GetContactBiasName(contact) contact_model_name = GetContactNodeModelName(contact) eq = "Potential - {0}".format(contact_bias_name) CreateContactNodeModel(device, contact, contact_model_name, eq) CreateContactNodeModelDerivative(device, contact, contact_model_name, eq, "Potential") #TODO: make everyone use dfield if not InEdgeModelList(device, region, contactcharge_edge): CreateEdgeModel(device, region, contactcharge_edge, "Permittivity*EField") CreateEdgeModelDerivatives(device, region, contactcharge_edge, "Permittivity*EField", "Potential") ds.contact_equation(device=device, contact=contact, name="PotentialEquation", node_model=contact_model_name, edge_charge_model=contactcharge_edge)
edge_model="DField", variable_update="default") # the topbias is a circuit node, and we want to prevent it from being overridden by a parameter devsim.set_parameter(device=device, region=region, name="botbias", value=0.0) for name, equation in ( ("topnode_model", "Potential - topbias"), ("topnode_model:Potential", "1"), ("topnode_model:topbias", "-1"), ("botnode_model", "Potential - botbias"), ("botnode_model:Potential", "1"), ): devsim.node_model(device=device, region=region, name=name, equation=equation) # attached to circuit node devsim.contact_equation(device=device, contact="top", name="PotentialEquation", variable_name="Potential", node_model="topnode_model", edge_charge_model="DField", circuit_node="topbias") # attached to ground devsim.contact_equation(device=device, contact="bot", name="PotentialEquation", variable_name="Potential", node_model="botnode_model", edge_charge_model="DField") # # Voltage source # devsim.circuit_element(name="V1", n1=1, n2=0, value=1.0, acreal=1.0) devsim.circuit_element(name="R1", n1="topbias", n2=1, value=1e3) # devsim.solve(type="dc", absolute_error=1.0, relative_error=1e-10, maximum_iterations=30) # print(devsim.get_contact_charge(device=device, contact="top", equation="PotentialEquation")) print(devsim.get_contact_charge(device=device, contact="bot", equation="PotentialEquation"))
devsim.edge_model(device=device, region=region, name="ElectricField", equation="(Potential@n0 - Potential@n1)*EdgeInverseLength") devsim.edge_model(device=device, region=region, name="ElectricField:Potential@n0", equation="EdgeInverseLength") devsim.edge_model(device=device, region=region, name="ElectricField:Potential@n1", equation="-EdgeInverseLength") devsim.set_parameter(device=device, region=region, name="topbias", value=1.0e-0) devsim.set_parameter(device=device, region=region, name="botbias", value=0.0) devsim.edge_model(device=device, region=region, name="PotentialEdgeFlux", equation="Permittivity*ElectricField") devsim.edge_model(device=device, region=region, name="PotentialEdgeFlux:Potential@n0", equation="diff(Permittivity*ElectricField, Potential@n0)") devsim.edge_model(device=device, region=region, name="PotentialEdgeFlux:Potential@n1", equation="-PotentialEdgeFlux:Potential@n0") devsim.equation(device=device, region=region, name="PotentialEquation", variable_name="Potential", edge_model="PotentialEdgeFlux", variable_update="default") devsim.node_model(device=device, region=region, name="topnode_model" , equation="Potential - topbias") devsim.node_model(device=device, region=region, name="topnode_model:Potential", equation="1") devsim.node_model(device=device, region=region, name="botnode_model" , equation="Potential - botbias") devsim.node_model(device=device, region=region, name="botnode_model:Potential", equation="1") devsim.contact_equation(device=device, contact="top", name="PotentialEquation", variable_name="Potential", node_model="topnode_model", edge_charge_model="PotentialEdgeFlux") devsim.contact_equation(device=device, contact="bot", name="PotentialEquation", variable_name="Potential", node_model="botnode_model", edge_charge_model="PotentialEdgeFlux") devsim.solve(type="dc", absolute_error=1.0, relative_error=1e-10, maximum_iterations=30) print(devsim.get_contact_charge(device=device, contact="top", equation="PotentialEquation")) print(devsim.get_contact_charge(device=device, contact="bot", equation="PotentialEquation")) devsim.write_devices(file="trimesh3.msh", type="devsim_data")