Exemple #1
0
 def set_parameters_for(self, device_name, region_name):
     from ds import set_parameter
     props = [
         p for p in dir(self) if not p.startswith('_')
         and isinstance(getattr(self, p), MaterialProperty)
     ]
     for pname in props:
         set_parameter(device=device_name,
                       region=region_name,
                       name=pname,
                       value=getattr(self, pname))
Exemple #2
0
 def set_parameters_for(self, device_name, region_name):
     props = [
         p for p in dir(self)
         if not p.startswith('_') and isinstance(getattr(self, p), MaterialProperty)
     ]
     for pname in props:
         set_parameter(
             device=device_name,
             region=region_name,
             name=pname, value=getattr(self, pname).value
         )
         log.debug('set_parameter(device={}, region={}, name={}, value={})'.format(
             device_name, region_name, pname, getattr(self, pname).value))
Exemple #3
0
    def set_parameters_for(self, device, region):
        """
        Use this function to register the parameters of this class into the
        simulation context. Internally uses ds.set_parameters()
        """
        props = [
            pname for pname in dir(self)
            if not pname.startswith('_') and not callable(getattr(self, pname))
        ]

        for propname in props:
            set_parameter(device=device,
                          region=region,
                          name=propname,
                          value=getattr(self, propname))
Exemple #4
0
def rampbias(device, contact, end_bias, step_size, min_step, max_iter,
             rel_error, abs_error, callback):
    '''
    Ramps bias with assignable callback function
  '''
    start_bias = ds.get_parameter(device=device,
                                  name=GetContactBiasName(contact))
    if (start_bias < end_bias):
        step_sign = 1
    else:
        step_sign = -1
    last_bias = start_bias
    while (abs(last_bias - end_bias) > min_step):
        print(("last end %e %e") % (last_bias, end_bias))
        next_bias = last_bias + step_sign * step_size
        if next_bias < end_bias:
            next_step_sign = 1
        else:
            next_step_sign = -1

        if next_step_sign != step_sign:
            next_bias = end_bias
            print("setting to last bias %e" % (end_bias))
            print("setting next bias %e" % (next_bias))
        ds.set_parameter(device=device,
                         name=GetContactBiasName(contact),
                         value=next_bias)
        try:
            ds.solve(type="dc",
                     absolute_error=abs_error,
                     relative_error=rel_error,
                     maximum_iterations=max_iter)
        except ds.error as msg:
            if msg[0].find("Convergence failure") != 0:
                raise
            ds.set_parameter(device=device,
                             name=GetContactBiasName(contact),
                             value=last_bias)
            step_size *= 0.5
            print("setting new step size %e" % (step_size))
            if step_size < min_step:
                raise "Min step size too small"
            continue
        print("Succeeded")
        last_bias = next_bias
        callback()
Exemple #5
0
def set_dd_parameters(device,
                      region,
                      permittivity=11.1,
                      n_i=1E10,
                      T=300,
                      mu_n=400,
                      mu_p=200,
                      taun=1E-5,
                      taup=1E-5):
    names = [
        'Permittivity', 'ElectronCharge', 'n_i', 'T', 'kT', 'V_t', 'mu_n',
        'mu_p', 'n1', 'p1', 'taun', 'taup'
    ]
    values = [
        permittivity * eps_0, q, n_i, T, k * T, k * T / q, mu_n, mu_p, n_i,
        n_i, taun, taup
    ]
    for name, value in zip(names, values):
        ds.set_parameter(device=device, region=region, name=name, value=value)
Exemple #6
0
    def solve(self, *args, **kwargs):
        if not args and not kwargs:
            self.initial_solution()
        elif kwargs.get('type', '') == 'ramp':
            kwargs['type'] = 'dc'
            start = kwargs.pop('start')
            stop = kwargs.pop('stop')
            step = kwargs.pop('step')
            contact = kwargs.pop('contact')
            for v in range(start, stop, step):
                set_parameter(device=self.name,
                              name=self._contact_bias_name(contact),
                              value=v)
                solve(**kwargs)
                self.print_currents()
        else:
            solve(*args, **kwargs)

        for mdl in self._models:
            mdl.solve(*args, **kwargs)
Exemple #7
0
    def initial_solution(self):
        self.setup_context()
        for region in self.mesh.regions:
            # Create Potential, Potential@n0, Potential@n1
            CreateSolution(self.name, region, "Potential")

            # Create potential only physical models
            # TODO: move to materials, relate region with material
            CreateSiliconPotentialOnly(self.name, region)

            # Set up the contacts applying a bias
            # TODO: Try to use self.contacts instead it is more correct for
            # the bias to be 0, and it looks like there are side effects

            for c in self.mesh.contacts:
                set_parameter(device=self.name,
                              name=self._contact_bias_name(c),
                              value=0.0)
                # TODO: move to models module
                CreateSiliconPotentialOnlyContact(self.name, region, c)
Exemple #8
0
def rampbias(device, contact, end_bias, step_size, min_step, max_iter, rel_error, abs_error, callback):
  '''
    Ramps bias with assignable callback function
  '''
  start_bias=ds.get_parameter(device=device, name=GetContactBiasName(contact))
  if (start_bias < end_bias):
    step_sign=1
  else:
    step_sign=-1
  last_bias=start_bias
  while(abs(last_bias - end_bias) > min_step):
    print("last end %e %e") % (last_bias, end_bias)
    next_bias=last_bias + step_sign * step_size
    if next_bias < end_bias:
      next_step_sign=1
    else:
      next_step_sign=-1

    if next_step_sign != step_sign:
      next_bias=end_bias
      print "setting to last bias %e" % (end_bias)
      print "setting next bias %e" % (next_bias)
    ds.set_parameter(device=device, name=GetContactBiasName(contact), value=next_bias)
    try:
      ds.solve(type="dc", absolute_error=abs_error, relative_error=rel_error, maximum_iterations=max_iter)
    except ds.error as msg:
      if msg[0].find("Convergence failure") != 0:
        raise
      ds.set_parameter(device=device, name=GetContactBiasName(contact), value=last_bias)
      step_size *= 0.5
      print "setting new step size %e" % (step_size)
      if step_size < min_step:
        raise "Min step size too small"
      continue
    print "Succeeded"
    last_bias=next_bias
    callback()
Exemple #9
0
def set_parameters(device=None, region=None, **kwargs):
    # TODO check if set_parameters works wihtout setting a device? Docs says it does...
    # if device is None:
    #     device = ds.get_device_list()[0]
    if device is None and region is None:
        for name, value in kwargs.items():
            ds.set_parameter(name=name, value=value)
    elif region is None:
        for name, value in kwargs.items():
            ds.set_parameter(device=device, name=name, value=value)
    else:
        for name, value in kwargs.items():
            ds.set_parameter(device=device, region=region, name=name, value=value)
Exemple #10
0
 def setup_context(self):
     """
         Initialize the context for the equations. Basically sets some variables.
         Region is an instance of the mesh.Region class
     """
     # Region context
     from pydevsim import T, kb, q
     for region in self.mesh.regions:
         for n, v in region.material.parameters.items():
             set_parameter(device=self.name,
                           region=region.name,
                           name=n,
                           value=v)
         # General
         set_parameter(device=self.name,
                       region=region.name,
                       name="ElectronCharge",
                       value=q)
         set_parameter(device=self.name,
                       region=region.name,
                       name="q",
                       value=q)
         set_parameter(device=self.name,
                       region=region.name,
                       name="T",
                       value=T)
         set_parameter(device=self.name,
                       region=region.name,
                       name="kT",
                       value=kb * T)
         set_parameter(device=self.name,
                       region=region.name,
                       name="V_t",
                       value=kb * T / q)
Exemple #11
0
         relative_error=1e-10,
         maximum_iterations=30)
# for region in regions:
#     DriftDiffusionInitialSolution(device, region)

###
### Drift diffusion simulation at equilibrium
###
currs = []
volts = []
bias_contact = "top_n1"
for volt in range(-20, 20, 1):
    volt = volt / 10
    volts.append(volt)
    ds.set_parameter(device=device,
                     name=f"{bias_contact}_bias",
                     value=float(volt))
    ds.solve(type="dc",
             absolute_error=1e1,
             relative_error=1e-10,
             maximum_iterations=30)
    e_current = ds.get_contact_current(device=device,
                                       contact=bias_contact,
                                       equation="ElectronContinuityEquation")
    h_current = ds.get_contact_current(device=device,
                                       contact=bias_contact,
                                       equation="HoleContinuityEquation")
    current = e_current + h_current
    currs.append(current)
print(volts, currs)
plt.plot(volts, currs)
Exemple #12
0
def SetSiliconParameters(device,
                         region,
                         T=300,
                         esp_si=11.1,
                         n_i=1E10,
                         mu_n=400,
                         mu_p=200,
                         tau_n=1E-5,
                         tau_p=1E-5):
    '''
    Sets physical parameters assuming constants
  '''
    #### TODO: make T a free parameter and T dependent parameters as models
    ds.set_parameter(device=device,
                     region=region,
                     name="Permittivity",
                     value=esp_si * eps_0)
    ds.set_parameter(device=device,
                     region=region,
                     name="ElectronCharge",
                     value=q)
    ds.set_parameter(device=device, region=region, name="n_i", value=n_i)
    ds.set_parameter(device=device, region=region, name="T", value=T)
    ds.set_parameter(device=device, region=region, name="kT", value=k * T)
    ds.set_parameter(device=device, region=region, name="V_t", value=k * T / q)
    ds.set_parameter(device=device, region=region, name="mu_n", value=mu_n)
    ds.set_parameter(device=device, region=region, name="mu_p", value=mu_p)
    #default SRH parameters
    ds.set_parameter(device=device, region=region, name="n1", value=n_i)
    ds.set_parameter(device=device, region=region, name="p1", value=n_i)
    ds.set_parameter(device=device, region=region, name="taun", value=tau_n)
    ds.set_parameter(device=device, region=region, name="taup", value=tau_p)
Exemple #13
0
ds.add_1d_interface(mesh=meshname,
                    tag=interface_tag,
                    name=f"{CdS_region}_to_{CdTe_region}_interface")
ds.add_1d_contact(material='metal',
                  mesh=meshname,
                  tag=bottom_tag,
                  name=bottom_tag)
ds.finalize_mesh(mesh=meshname)

ds.create_device(mesh=meshname, device=device)

# Add some physics

for region, params in zip(regions, [CdS_params, CdTe_params]):
    for name, value in params.items():
        ds.set_parameter(device=device, region=region, name=name, value=value)
    set_dd_parameters(device=device, region=region)

# Initial DC solution
ds.solve(type="dc",
         absolute_error=1.0e10,
         relative_error=1e10,
         maximum_iterations=150)
# for region in regions:
#     DriftDiffusionInitialSolution(device, region)

###
### Drift diffusion simulation at equilibrium
###
currs = []
volts = []
Exemple #14
0
def set_dd_parameters(device,
                      region,
                      permittivity=11.1,
                      n_i=1E10,
                      T=300,
                      mu_n=400,
                      mu_p=200,
                      taun=1E-5,
                      taup=1E-5):
    names = [
        'permittivity', 'q', 'n_i', 'T', 'k', 'kT', 'V_t', 'mobility_n',
        'mobility_p', 'n1', 'p1', 'taun', 'taup'
    ]
    values = [
        permittivity * eps_0, q, n_i, T, k, k * T, k * T / q, mu_n, mu_p, n_i,
        n_i, taun, taup
    ]
    for name, value in zip(names, values):
        ds.set_parameter(device=device, region=region, name=name, value=value)

    # Setup the solutions for the potential, electron and hole densities
    pot = 'potential'
    electron_density = 'electron_density'
    hole_density = 'hole_density'
    for var in [pot, electron_density, hole_density]:
        create_solution(device=device, region=region, name=var)

    # Now for some poisson's equation
    # Create some nodemodels
    n_ie = 'n_ie', f"n_i*exp(q*{pot}/k*T)"  # Intrinsic electron density
    n_ih = 'n_ih', f'n_i^2/{n_ie[0]}'  # Intrinsic hole density
    net_n_i = 'net_n_i', f'kahan4(-{n_ie[0]}, {n_ih[0]}, p_doping, -n_doping)'  # Net intrinsic charge
    net_n_i_charge = 'net_n_i_charge', f'q*{net_n_i[0]}'  #PotentialIntrinsicCharge
    for name, eq in [n_ie, n_ih, net_n_i, net_n_i_charge]:
        ds.node_model(device=device, region=region, name=name, equation=eq)
        create_derivatives(device, region, name, eq, pot)

    E_field = 'E_field', f'({pot}@n0-{pot}@n1)*EdgeInverseLength'
    D_field = 'D_field', 'E_field * permittivity'  #PotentialEdgeFlux ?? wtf

    # Initialize the electron and hole densities
    for carrier, init in zip([electron_density, hole_density], [n_ie, n_ih]):
        ds.set_node_values(device=device,
                           region=region,
                           name=carrier,
                           init_from=init[0])

    # setup edge nodes
    for edge_name, eq in [E_field, D_field]:
        ds.edge_model(device=device,
                      region=region,
                      name=edge_name,
                      equation=eq)
        create_derivatives(device, region, edge_name, eq, pot)

    # Create PE
    poisson_RHS = 'PoissonRHS', f'({hole_density} - {electron_density} + p_doping - n_doping)'  #*q/(permittivity)'
    # AKA pne
    ds.node_model(device=device,
                  region=region,
                  name=poisson_RHS[0],
                  equation=poisson_RHS[1])
    create_derivatives(device, region, poisson_RHS[0], poisson_RHS[1],
                       hole_density, electron_density)
    ds.equation(device=device,
                region=region,
                name="PoissonEquation",
                variable_name=pot,
                node_model=poisson_RHS[0],
                edge_model=D_field[0])

    # Use stupid bernouli formalism
    # Check if exists?
    ds.edge_from_node_model(device=device, region=region, node_model=pot)
    beta_vdiff = 'beta_vdiff', f'({pot}@n0 - {pot}@n1)*q/kT'
    ds.edge_model(device=device,
                  region=region,
                  name=beta_vdiff[0],
                  equation=beta_vdiff[1])
    bernouli = 'bern', f'B({beta_vdiff[0]})'
    ds.edge_model(device=device,
                  region=region,
                  name=bernouli[0],
                  equation=bernouli[1])

    # Create continuity equations
    E_qf_n = (
        'quasi_fermi_n',
        f'q*({pot}-electron_affinity) + k*T*log({electron_density}/N_cond)')
    E_qf_p = (
        'quasi_fermi_p',
        f'q*({pot}-electron_affinity) - k*T*log({hole_density}/N_val) - band_gap'
    )
    J_e = 'e_current', f'q*mobility_n*{electron_density}*EdgeInverseLength*({E_qf_n[0]}@n0-{E_qf_n[0]}@n1)'
    J_h = 'h_current', f'q*mobility_p*{hole_density}*EdgeInverseLength*({E_qf_p[0]}@n0-{E_qf_p[0]}@n1)'

    for J in [E_qf_n, E_qf_p, J_e, J_h]:
        ds.edge_model(device=device, region=region, name=J[0], equation=J[1])
        ds.node_model(device=device, region=region, name=J[0], equation=J[1])
        for node_model in [pot, electron_density, hole_density]:
            # Check if exists?!
            ds.edge_from_node_model(device=device,
                                    region=region,
                                    node_model=node_model)
            create_derivatives(device, region, J[0], J[1], node_model)

    for node_model in [n_ie, n_ih, net_n_i, net_n_i_charge]:
        ds.print_node_values(device=device, region=region, name=node_model[0])

    for edge_model in [E_qf_n, E_qf_p, J_e, J_h]:
        ds.print_edge_values(device=device, region=region, name=edge_model[0])
Exemple #15
0
                 material="InAs",
                 region=n2_region,
                 tag1="bot_b",
                 tag2="bot_n2")

ds.add_1d_interface(mesh=meshname,
                    tag="bot_b",
                    name=f"{b_region}_to_{n2_region}")
ds.add_1d_contact(mesh=meshname, name="bot_n2", tag="bot_n2", material="metal")
ds.finalize_mesh(mesh=meshname)
ds.create_device(mesh=meshname, device=device)

####
#### Set parameters for 300 K
####
ds.set_parameter(name="T", value=300)
for region in regions:
    if region == b_region:
        affinity = b_affinity
        bandgap = b_band_gap
        doping = b_doping
    else:
        affinity = n_affinity
        bandgap = n_band_gap
        doping = 1E11
    SetSiliconParameters(device, region, Affinity=affinity, EG300=bandgap)
    set_parameter(device=device, region=region, name="taun", value=1e-8)
    set_parameter(device=device, region=region, name="taup", value=1e-8)
    set_parameter(device=device, region=region, name="n1", value=1e10)
    set_parameter(device=device, region=region, name="p1", value=1e10)
Exemple #16
0
    def setup_drift_diffusion(self,
                              dielectric_const=11.9,
                              intrinsic_carriers=1E10,
                              work_function=4.05,
                              band_gap=1.124,
                              Ncond=3E19,
                              Nval=3E19,
                              mobility_n=1107,
                              mobility_p=424.6,
                              Nacceptors=0,
                              Ndonors=0):
        """
        Sets up equations for a drift-diffusion style of dc current transport.

        kwargs here are device-level parameters, imbuing all regions with these properties
        If a specific region or material is to have a different set of parameters, they can be set through the
        Region constructor.
        :param dielectric_const:
        :param intrinsic_carriers:
        :param work_function:
        :param band_gap:
        :param Ncond:
        :param Nval:
        :param mobility_n:
        :param mobility_p:
        :param Nacceptors:
        :param Ndonors:
        :return:
        """
        # Begin legacy copy-paste job
        # Set silicon parameters
        device = self.name
        region = self.regions[0].name
        eps_si = dielectric_const
        n_i = 1E10
        k = kb
        mu_n = mobility_n
        mu_p = mobility_p
        set_parameter(device=device,
                      region=region,
                      name="Permittivity",
                      value=eps_si * eps_0)
        set_parameter(device=device,
                      region=region,
                      name="ElectronCharge",
                      value=q)
        set_parameter(device=device, region=region, name="n_i", value=n_i)
        set_parameter(device=device, region=region, name="T", value=T)
        set_parameter(device=device, region=region, name="kT", value=k * T)
        set_parameter(device=device,
                      region=region,
                      name="V_t",
                      value=k * T / q)
        set_parameter(device=device, region=region, name="mu_n", value=mu_n)
        set_parameter(device=device, region=region, name="mu_p", value=mu_p)
        # default SRH parameters
        set_parameter(device=device, region=region, name="n1", value=n_i)
        set_parameter(device=device, region=region, name="p1", value=n_i)
        set_parameter(device=device, region=region, name="taun", value=1e-5)
        set_parameter(device=device, region=region, name="taup", value=1e-5)
        # CreateNodeModel 3 times
        for name, value in [('Acceptors', "1.0e18*step(0.5e-5-x)"),
                            ('Donors', "1.0e18*step(x-0.5e-5)"),
                            ('NetDoping', "Donors-Acceptors")]:
            result = node_model(device=device,
                                region=region,
                                name=name,
                                equation=value)
            logger.debug(f"NODEMODEL {device} {region} {name} '{result}'")
        print_node_values(device=device, region=region, name="NetDoping")
        model_name = "Potential"
        node_solution(name=model_name, device=device, region=region)
        edge_from_node_model(node_model=model_name,
                             device=device,
                             region=region)
        # Create silicon potentialOnly
        if model_name not in get_node_model_list(device=device, region=region):
            logger.debug("Creating Node Solution Potential")
            node_solution(device=device, region=region, name=model_name)
            edge_from_node_model(node_model=model_name,
                                 device=device,
                                 region=region)

        # require NetDoping
        for name, eq in (
            ("IntrinsicElectrons", "n_i*exp(Potential/V_t)"),
            ("IntrinsicHoles", "n_i^2/IntrinsicElectrons"),
            ("IntrinsicCharge",
             "kahan3(IntrinsicHoles, -IntrinsicElectrons, NetDoping)"),
            ("PotentialIntrinsicCharge", "-ElectronCharge * IntrinsicCharge")):
            node_model(device=device, region=region, name=name, equation=eq)
            node_model(device=device,
                       region=region,
                       name=f"{name}:{model_name}",
                       equation=f"simplify(diff({eq},{model_name}))")
            # CreateNodeModelDerivative(device, region, name, eq, model_name)

        ### TODO: Edge Average Model
        for name, eq in (("ElectricField",
                          "(Potential@n0-Potential@n1)*EdgeInverseLength"),
                         ("PotentialEdgeFlux",
                          "Permittivity * ElectricField")):
            edge_model(device=device, region=region, name=name, equation=eq)
            edge_model(device=device,
                       region=region,
                       name=f"{name}:{model_name}@n0",
                       equation=f"simplify(diff({eq}, {model_name}@n0))")
            edge_model(device=device,
                       region=region,
                       name=f"{name}:{model_name}@n1",
                       equation=f"simplify(diff({eq}, {model_name}@n1))")

        equation(device=device,
                 region=region,
                 name="PotentialEquation",
                 variable_name=model_name,
                 node_model="PotentialIntrinsicCharge",
                 edge_model="PotentialEdgeFlux",
                 variable_update="log_damp")

        # Set up the contacts applying a bias
        is_circuit = False
        for contact_name in get_contact_list(device=device):
            set_parameter(device=device,
                          name=f"{contact_name}_bias",
                          value=0.0)
            # CreateSiliconPotentialOnlyContact(device, region, contact_name)
            # Start
            # Means of determining contact charge
            # Same for all contacts
            if not InNodeModelList(device, region, "contactcharge_node"):
                create_node_model(device, region, "contactcharge_node",
                                  "ElectronCharge*IntrinsicCharge")
            #### TODO: This is the same as D-Field
            if not InEdgeModelList(device, region, "contactcharge_edge"):
                CreateEdgeModel(device, region, "contactcharge_edge",
                                "Permittivity*ElectricField")
                create_edge_model_derivatives(device, region,
                                              "contactcharge_edge",
                                              "Permittivity*ElectricField",
                                              "Potential")
                #  set_parameter(device=device, region=region, name=GetContactBiasName(contact), value=0.0)
            contact_bias_name = f"{contact_name}_bias"
            contact_model_name = f"{contact_name}nodemodel"
            contact_model = f"Potential -{contact_bias_name} + ifelse(NetDoping > 0, -V_t*log({CELEC_MODEL!s}/n_i), V_t*log({CHOLE_MODEL!s}/n_i))"\

            CreateContactNodeModel(device, contact_name, contact_model_name,
                                   contact_model)
            # Simplify it too complicated
            CreateContactNodeModel(
                device, contact_name, "{0}:{1}".format(contact_model_name,
                                                       "Potential"), "1")
            if is_circuit:
                CreateContactNodeModel(
                    device, contact_name,
                    "{0}:{1}".format(contact_model_name,
                                     contact_bias_name), "-1")

            if is_circuit:
                contact_equation(device=device,
                                 contact=contact_name,
                                 name="PotentialEquation",
                                 variable_name="Potential",
                                 node_model=contact_model_name,
                                 edge_model="",
                                 node_charge_model="contactcharge_node",
                                 edge_charge_model="contactcharge_edge",
                                 node_current_model="",
                                 edge_current_model="",
                                 circuit_node=contact_bias_name)
            else:
                contact_equation(device=device,
                                 contact=contact_name,
                                 name="PotentialEquation",
                                 variable_name="Potential",
                                 node_model=contact_model_name,
                                 edge_model="",
                                 node_charge_model="contactcharge_node",
                                 edge_charge_model="contactcharge_edge",
                                 node_current_model="",
                                 edge_current_model="")
            # Biggie

        # Initial DC solution
        solve(type="dc",
              absolute_error=1.0,
              relative_error=1e-10,
              maximum_iterations=30)

        drift_diffusion_initial_solution(device, region)

        solve(type="dc",
              absolute_error=1e10,
              relative_error=1e-10,
              maximum_iterations=30)
Exemple #17
0
 def set_bias(self, tag, bias_volt):
     set_parameter(device=self.name,
                   name=f"{tag}_bias",
                   value=float(bias_volt))
Exemple #18
0
from adaptusim import setup_logger

logger = setup_logger(__name__)
# Fundamental Constants
# Permitivity of free space
eps_0 = 8.854187817e-14  # F/cm^2
# The electron charge quanta
q = 1.60217662e-19  # Couloumbs
# Boltzmann's constant
kb = 1.3806503e-23  # J/K
# Planck's constant
planck_h = 6.626E-34  #J*s
# Default Ambient temperature
T = 300  # K
# Thermal energy
kT = kb * T
# Thermal voltage
Vt = kb * T / q
# Set them globally
for name in ['eps_0', 'q', 'kb', 'planck_h', 'T', 'kT', 'Vt']:
    value = eval(name)
    logger.info(f"Now setting global variable {name} to {value:.3g}")
    set_parameter(name=name, value=value)

DS_DATADIR = abspath(join(dirname(__file__), 'data'))

ECE_NAME = "ElectronContinuityEquation"
HCE_NAME = "HoleContinuityEquation"
CELEC_MODEL = "(1e-10 + 0.5*abs(NetDoping+(NetDoping^2 + 4 * n_i^2)^(0.5)))"
CHOLE_MODEL = "(1e-10 + 0.5*abs(-NetDoping+(NetDoping^2 + 4 * n_i^2)^(0.5)))"
Exemple #19
0
    ds.create_device(mesh=meshname, device=device)
    setup_physical_constants(device, region)
    setup_poisson_parameters(device, region, p_doping=1e18)
    setup_poisson(device, region)
    get_ds_status()
    ds.solve(type="dc",
             absolute_error=10,
             relative_error=10,
             maximum_iterations=30)
    get_ds_status()
    print("Post solve")
    setup_continuity(device, region)
    ds.solve(type="dc",
             absolute_error=10,
             relative_error=1e1,
             maximum_iterations=30)
    for volt in [-1, 0, 1]:
        ds.set_parameter(device=device,
                         name='top_contact_bias',
                         value=float(volt))
        chrg = ds.get_node_model_values(device=device,
                                        region=region,
                                        name=total_charge)
        pot = ds.get_edge_model_values(device=device,
                                       region=region,
                                       name=e_field)
        for data in [chrg, pot]:
            plt.figure()
            plt.plot(data)
        plt.show()
# Ei = (Ec + Ev) / 2