This is a quick and dirty copy/paste job but it runs and the output current is reacting to the optical generation parameters.
# Copyright 2013 DEVSIM LLC
#
# SPDX-License-Identifier: Apache-2.0
from devsim import *
from devsim.python_packages.simple_physics import *
import devsim.python_packages.Klaassen as kla
import diode_common
def CreateSRHOptical(device: str, region: str):
"""
Modified SRH model to include constant carrier generation, used to emulate optical generation
:param device:
:param region:
:return:
"""
# init optical generation to 0.0 on all nodes
set_parameter(device=device, name="OptScale", value=0.0)
node_solution(device=device, region=region, name="OptGen")
xpos = get_node_model_values(device=device, region=region, name="x")
optical_generation = [0.0] * len(xpos)
set_node_values(device=device, region=region, name="OptGen", values=optical_generation)
USRH = "(Electrons*Holes - n_i^2)/(taup*(Electrons + n1) + taun*(Holes + p1))"
Gn = "-ElectronCharge * (USRH - OptGen * OptScale)"
Gp = "+ElectronCharge * (USRH - OptGen * OptScale)"
CreateNodeModel(device, region, "USRH", USRH)
CreateNodeModel(device, region, "ElectronGeneration", Gn)
CreateNodeModel(device, region, "HoleGeneration", Gp)
for i in ("Electrons", "Holes"):
CreateNodeModelDerivative(device, region, "USRH", USRH, i)
CreateNodeModelDerivative(device, region, "ElectronGeneration", Gn, i)
CreateNodeModelDerivative(device, region, "HoleGeneration", Gp, i)
def print_currents(device, contact):
"""
Print out contact currents
"""
ece_name = "ElectronContinuityEquation"
hce_name = "HoleContinuityEquation"
contact_bias_name = GetContactBiasName(contact)
electron_current= get_contact_current(device=device, contact=contact, equation=ece_name)
hole_current = get_contact_current(device=device, contact=contact, equation=hce_name)
total_current = electron_current + hole_current
if contact in ["top", "bot"]:
voltage = get_circuit_node_value(solution='dcop', node=f"n{contact}")
else:
voltage = get_parameter(device=device, name=GetContactBiasName(contact))
data = (voltage, electron_current, hole_current, total_current)
print(f"{contact:10}{voltage:+.3e}\t{electron_current:+.3e}\t{hole_current:+.3e}\t{total_current:+.3e}")
return data
def print_all_currents():
"""
Prints all currents to console and returns outmap of values. !Currently only functional when all contacts are
silicon contacts!
:return:
"""
print("\nSolution:")
print("{0:10}{1:15}{2:12}{3:12}{4:10}".format("Contact", "Voltage", "Electron", "Hole", "Total"))
print(" Current Current Current")
device_list = get_device_list()
for device in device_list:
contact_list = get_contact_list(device=device)
outmap = {}
for contact in contact_list:
outmap[contact] = print_currents(device, contact)
print_circuit_solution()
return outmap
def print_circuit_solution():
print('Circuit Solution')
nodes = get_circuit_node_list()
for node in get_circuit_node_list():
r = get_circuit_node_value(solution='dcop', node=node)
print("%s\t%1.15e" % (node, r))
set_parameter(name="debug_level", value="info")
#set_parameter(name="threads_available", value=8)
#set_parameter(name="threads_task_size", value=1024)
set_parameter(name="extended_solver", value="True")
set_parameter(name="extended_model", value="True")
set_parameter(name="extended_equation", value="True")
device="diode3d"
region="Bulk"
diode_common.Create3DGmshMesh(device, region)
# this is the devsim format
write_devices (file="gmsh_diode3d_out.msh")
diode_common.SetParameters(device=device, region=region)
set_parameter(device=device, region=region, name="taun", value=1e-3)
set_parameter(device=device, region=region, name="taup", value=1e-3)
v_source_top = circuit_element(name="VSourceTop", n1="ntop_res", n2="GND", value=0.0)
v_source_bot = circuit_element(name="VSourceBot", n1="nbot_res", n2="GND", value=0.0)
r_source_top = circuit_element(name="RSourceTop", n1="ntop_res", n2="ntop", value=1.0)
r_source_bot = circuit_element(name="RSourceBot", n1="nbot_res", n2="nbot", value=1.0)
c_source_top = circuit_element(name="CSourceTop", n1="ntop", n2="GND", value=1e-12)
#c_source_bot = circuit_element(name="CSourceBot", n1="nbot", n2="GND", value=1e-17)
circuit_node_alias(node="ntop", alias="top_bias")
circuit_node_alias(node="nbot", alias="bot_bias")
####
#### NetDoping
####
node_model(device=device, region=region, name="Acceptors", equation="1.0e18*step(0.5e-5-z);")
node_model(device=device, region=region, name="Donors", equation="1.0e18*step(z-0.5e-5);")
node_model(device=device, region=region, name="NetDoping", equation="Donors-Acceptors;")
node_model(device=device, region=region, name="AbsDoping", equation="abs(NetDoping)")
node_model(device=device, region=region, name="logDoping", equation="log(AbsDoping)/log(10)")
diode_common.InitialSolution(device, region, circuit_contacts=["top", "bot"])
####
#### Initial DC solution
####
solve(type="transient_dc", absolute_error=1e-10, relative_error=1e-12, maximum_iterations=30)
###
### Drift diffusion simulation at equilibrium
###
diode_common.DriftDiffusionInitialSolution(device, region, circuit_contacts=["top", "bot"])
kla.Set_Mobility_Parameters(device, region)
kla.Klaassen_Mobility(device, region)
solve(type="transient_dc", absolute_error=1e-10, relative_error=1e-9, maximum_iterations=50)
# init optics
CreateSRHOptical(device=device, region=region)
xpos = get_node_model_values(device=device, region=region, name="x")
# set generation parameters, use set_parameter(device=device, name="OptScale", value=X) in a loop to ramp optical
# generation up or down if required
optical_generation = [1e18] * len(xpos)
set_node_values(device=device, region=region, name="OptGen", values=optical_generation)
set_parameter(device=device, name="OptScale", value=1.0)
solve(type="transient_dc", absolute_error=1e-10, relative_error=1e-9, maximum_iterations=50)
v = -0.1
while v > -3.01:
circuit_alter(name="VSourceTop", value=v)
solve(type="transient_bdf1", absolute_error=1.0, relative_error=1e-09,
maximum_iterations=100, tdelta=1e-8, charge_error=1.0)
print_all_currents()
v -= 0.1
print("\n\n\nSteady State: -----------------------------------------------------------")
for i in range(50):
solve(type="transient_bdf1", absolute_error=1.0, relative_error=1e-09,
maximum_iterations=30, tdelta=1e-8, charge_error=1.0)
print_all_currents()