Exemplo n.º 1
0
def DriftDiffusionInitialSolution(device, region, circuit_contacts=None):
    ####
    #### drift diffusion solution variables
    ###
    CreateSolution(device, region, "Electrons")
    CreateSolution(device, region, "Holes")

    ####
    #### create initial guess from dc only solution
    ####
    ds.set_node_values(device=device,
                       region=region,
                       name="Electrons",
                       init_from="IntrinsicElectrons")
    ds.set_node_values(device=device,
                       region=region,
                       name="Holes",
                       init_from="IntrinsicHoles")

    ###
    ### Set up equations
    ###
    CreateSiliconDriftDiffusion(device, region)
    for i in ds.get_contact_list(device=device):
        if circuit_contacts and i in circuit_contacts:
            CreateSiliconDriftDiffusionAtContact(device, region, i, True)
        else:
            CreateSiliconDriftDiffusionAtContact(device, region, i)
Exemplo n.º 2
0
def setup_poisson(device, region, variable_update='log_damp', **kwargs):
    """
    Sets up poisson equation solution
    Requires:
     setup physical constants and setup poisson parameters
    :param kwargs:
    :return:
    """
    logger.debug("Setting up Poisson Equation")
    # These are variables that are to be solved during the simulation
    # for sol_variable in [hole_density, electron_density, potential, qfn, qfp]:
    for sol_variable in [potential, electron_density, hole_density]:
        create_solution(device, region, sol_variable)
    total_charge_eq = f'kahan3({hole_density},-{electron_density},{p_doping})' #f'{hole_density}-{electron_density}+{p_doping}-{n_doping}' #f'-{q}*kahan4({hole_density}, -{electron_density}, {p_doping}, -{n_doping})'
    int_chg_eq = '1e11'# f'({Nc}*{Nv})^(1/2)*exp(-{bandgap}/(2*k*T))'
    # Order matters!
    for name, eq in zip([intrinsic_charge,  total_charge, ],
                        [int_chg_eq, total_charge_eq,]):
        create_node_and_derivatives(device, region, name, eq, [potential, electron_density, hole_density])
    ds.edge_from_node_model(device=device, region=region,node_model=electron_density)
    ds.edge_from_node_model(device=device, region=region, node_model=hole_density)

    e_field_eq = f"({potential}@n0-{potential}@n1)*EdgeInverseLength"
    d_field_eq = f'{e_field}*{permittivity}*{eps_0}'
    for name, eq in zip([e_field, d_field],[e_field_eq, d_field_eq]):
        create_edge_and_derivatives(device, region, name, eq, [potential])

    # Lastly, setup the equation to solve for 'potential'
    # TODO check initial values
    ds.set_node_values(device=device, region=region, name=electron_density, init_from=intrinsic_charge)
    ds.set_node_values(device=device, region=region, name=hole_density, init_from=intrinsic_charge)
    ds.equation(device=device, region=region, name='PoissonEq', variable_name=potential,
                node_model=total_charge, edge_model=d_field, variable_update=variable_update)
Exemplo n.º 3
0
    def drift_diffusion_initial_solution(self):
        # TODO: move it to somewhere else
        # drift diffusion solution variables
        self.create_solution_variable("Electrons")
        self.create_solution_variable("Holes")

        for region in self.mesh.regions:
            # Create initial guess from DC only solution
            set_node_values(device=self.name,
                            region=region.name,
                            name="Electrons",
                            init_from="IntrinsicElectrons")
            set_node_values(device=self.name,
                            region=region.name,
                            name="Holes",
                            init_from="IntrinsicHoles")

            # Set up equations
            CreateSiliconDriftDiffusion(self.name, region.name)
            for c in self.mesh.contacts:
                CreateSiliconDriftDiffusionAtContact(self.name, region.name, c)
Exemplo n.º 4
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])