Table Of Contents

Previous topic

1. Quick Python Programming with Semiconductor Device Fundamentals

Next topic

3. PN Junction

This Page

2. Equilibrium Semiconductor Homework Solution

2.1. Instructions

Sample solutions are given below. Use the sample solution codes to generate reference plots. Compare them with plots you have obtained yourself. I have tried to show you how the codes we wrote earlier in “eqsemiv1.py” can be reused using import.

I have a habit of providing default parameter values to all of my functions, but you are not required to do this for homework codes.

You can start from reading the main() function which calls the functions for solving the 4 homework problems. These functions are very similar to the ones we created earlier, but each still requires a bit work.

A function is written for each homework problem, parameters can be changed. Default parameters are also provided inside the function. An array is “mutable” - so it is best to not use an array as default. Instead, I use a special object “None” as default value, when it is None, it means no default array values are provided, so I will generate an array inside the function.

If you do not understand “mutable”, you can ignore that part. All you have to do is to not forget providing an array of a function call’s argument that is an array.

You can change your background doping vale easily and observe how the semiconductor type is changed from one type to its opposite type as doping is changed.

2.2. Sample solution

First make sure you have the “eqsemiv1.py” from our previous tutorial. Again, the name should not be changed. Download the file here and place it in the same directory. Run.

Alternatively, in the same folder, create a new file, copy the codes below and paste them into your own codes

'''
Try writing a few function for each task below and call the functions from the main() function.
You can use my example functions as a starting point. Only minor changes are required in all cases.

Plot out p and n versus Nd, Nd range is from 1e14 to 1e20. You have a background Na of 1e16.
Plot out bands Ec, Ev, Ef, Ei versus Nd, Nd range is from 1e14 to 1e20. You have a background Na of 1e16.
Plot out p and n versus Na, Na range is from 1e14 to 1e20. You have a background Nd of 0.
Plot out bands Ec, Ev, Ef, Ei versus Na, Na range is from 1e14 to 1e20. You have a background Nd of 0.

'''


# use newer python3 print and 1/2=0.5
from __future__ import division, print_function


# import what need from what we wrote earlier in eqsemiv1.py
from eqsemiv1 import ni300k, nc300k, nv300k, eg300k, find_energies, find_pn
from numpy import logspace, empty
from myplot import myplot, show, new_ax, ColorCycler


def plot_pn_vs_nd_with_na(nds = None, na=0):

    # make a plot of p/n versus nd

    # create an array of nd, on log scale, from 1e5 to 1e20
    if nds == None:
        nds = logspace(5, 20, 50)

    # create place holders for p and n arrays
    ps = empty(len(nds))
    ns = empty(len(nds))

    # iterate over array nds, we also need index, so use "enumerate"
    for idx, nd in enumerate(nds):
        # !!! Note indentation is used here to define body of the for loop
        solution = find_pn(nd=nd, na=na, ni=ni300k)
        # see how we get p and n by key (name) in dictionary
        ps[idx] = solution['p']
        ns[idx] = solution['n']

    ax = new_ax()

    linep, axpn, fig = myplot(ax=ax,
           x=nds,
           y=ns,
           xlog=True,
           ylog=True,
           color='r',
           label='n',
           xlabel='$N_d (/cm^3)$',
           ylabel='$p,n(/cm^3)$')

    # continue to plot p on the same ax
    linen, axpn, fig = myplot(ax=ax, x=nds, y=ps, color='b',
           label='p')

    # save figure to a PDF
    # fig is an object, and has a method savefig
    #fig.savefig('pnvsnd.pdf')
    fig.savefig('pnvsnd.png')




def plot_bands_vs_nd_with_na(nds=None, na=0):

    solution = find_energies(nd=1e16, na=0, eg=eg300k, nc=nc300k, nv=nv300k, t=300)

    keys = solution.keys()

    bands = dict()


    if nds == None: # if nds is not provided, create one
        # create an array of nd, on log scale, from 1e5 to 1e20
        nds = logspace(5, 20, 50)

    num_nds = len(nds)


    for key in keys:
        bands[key] = empty(num_nds)

    for idx, nd in enumerate(nds):
        solution = find_energies(nd=nd, na=na, eg=eg300k, nc=nc300k, nv=nv300k, t=300)
        for key in keys:
            bands[key][idx] = solution[key]

    # now data is ready, let us plot them out

    cc = ColorCycler()

    axbands = new_ax()

    for key in keys:
        myplot(ax=axbands,
               x=nds,
               y=bands[key],
               xlog=True,
               color=cc.next(),
               label=key)

    axbands.set_xlabel('$N_d(/cm^3)$')
    axbands.set_ylabel('$Energies (eV)$')

    # change bottom of y-axis so that ev=0 can be clearly seen
    axbands.set_ylim(bottom=-0.2)

def plot_pn_vs_na_with_nd(nas = None, nd=0):

    # make a plot of p/n versus nd

    # create an array of na, on log scale, from 1e5 to 1e20
    if nas == None:
        nas = logspace(5, 20, 50)

    # create place holders for p and n arrays
    ps = empty(len(nas))
    ns = empty(len(nas))

    # iterate over array nds, we also need index, so use "enumerate"
    for idx, na in enumerate(nas):
        # !!! Note indentation is used here to define body of the for loop
        solution = find_pn(nd=nd, na=na, ni=ni300k)
        # see how we get p and n by key (name) in dictionary
        ps[idx] = solution['p']
        ns[idx] = solution['n']

    ax = new_ax()

    linep, axpn, fig = myplot(ax=ax,
           x=nas,
           y=ns,
           xlog=True,
           ylog=True,
           color='r',
           label='n',
           xlabel='$N_a (/cm^3)$',
           ylabel='$p,n(/cm^3)$')

    # continue to plot p on the same ax
    linen, axpn, fig = myplot(ax=ax, x=nas, y=ps, color='b',
           label='p')

    # save figure to a PDF
    # fig is an object, and has a method savefig
    #fig.savefig('pnvsnd.pdf')
    fig.savefig('pnvsnd.png')

    return axpn, fig



def plot_bands_vs_na_with_nd(nas=None, nd=0):

    solution = find_energies(nd=1e16, na=0, eg=eg300k, nc=nc300k, nv=nv300k, t=300)

    keys = solution.keys()

    bands = dict()


    if nas == None:
        # create an array of nd, on log scale, from 1e5 to 1e20
        nas = logspace(5, 20, 50)

    num_nas = len(nas)


    for key in keys:
        bands[key] = empty(num_nas)

    for idx, na in enumerate(nas):
        solution = find_energies(nd=nd, na=na, eg=eg300k, nc=nc300k, nv=nv300k, t=300)
        for key in keys:
            bands[key][idx] = solution[key]

    # now data is ready, let us plot them out

    cc = ColorCycler()

    axbands = new_ax()

    for key in keys:
        myplot(ax=axbands,
               x=nas,
               y=bands[key],
               xlog=True,
               color=cc.next(),
               label=key)

    axbands.set_xlabel('$N_a(/cm^3)$')
    axbands.set_ylabel('$Energies (eV)$')

    # change bottom of y-axis so that ev=0 can be clearly seen
    axbands.set_ylim(bottom=-0.2)



def main():

    # Homework 1 and 2
    nds = logspace(14, 20, 200)
    na = 1e16

    plot_pn_vs_nd_with_na(nds=nds, na=na)

    plot_bands_vs_nd_with_na(nds=nds, na=na)


    # Homework 3 and 4

    nas = logspace(14, 20, 200)
    nd = 1e16

    plot_pn_vs_na_with_nd(nas=nas, nd=nd)

    plot_bands_vs_na_with_nd(nas=nas, nd=nd)



if __name__ == '__main__':
    main()
    show()