Esempio n. 1
0
def plot_charge(device=None,regions=None, charge_names=None):
    """
    Plots the charge along the device
    :param device:
    :param regions:
    :param charge_names:
    :return:
    """
    if device is None:
        device = ds.get_device_list()[0]
    if regions is None:
        regions = ds.get_region_list(device=device)
    if charge_names is None:
        charge_names = ("Electrons", "Holes", "Donors", "Acceptors")
    plt.figure(figsize=(6, 2.7))
    labels = []
    for var_name in charge_names:
        total_x = np.array([])
        total_y = []
        for region in regions:
            labels.append(f"{var_name} in {region}")
            x = np.array(ds.get_node_model_values(device=device, region=region, name="x"))
            # print(var_name, min(x), max(x), min(x)*1e4, max(x)*1e4)
            total_x = np.append(total_x, x)
            y=ds.get_node_model_values(device=device, region=region, name=var_name)
            total_y.extend(y)
        # plt.axis([min(x), max(x), ymin, ymax])
            plt.semilogy(x*1e4, y)
    plt.xlabel('x (um)')
    plt.ylabel('Density (#/cm^3)')
    plt.legend(labels)
    plt.title('Charge Density')
Esempio n. 2
0
def get_ds_status():
    devices = ds.get_device_list()
    for device in devices:
        print("Device: " + device)
        regions = ds.get_region_list(device=device)
        for region in regions:
            print("\tRegion :" + region)
            params = ds.get_parameter_list(device=device, region=region)
            for param in params:
                val = ds.get_parameter(device=device,
                                       region=region,
                                       name=param)
                print(f"\t\t{param} = {val}")
            n_models = ds.get_node_model_list(device=device, region=region)
            for node_model in n_models:
                nmvals = ds.get_node_model_values(device=device,
                                                  region=region,
                                                  name=node_model)
                print(f"\t\t Node Model '{node_model}' = {nmvals!s}")
            e_models = ds.get_edge_model_list(device=device, region=region)
            for edge_model in e_models:
                emvals = ds.get_edge_model_values(device=device,
                                                  region=region,
                                                  name=edge_model)
                print(f"\t\t Edge Model '{edge_model}' = {emvals!s}")
        contacts = ds.get_contact_list(device=device)
        for contact in contacts:
            print("\tContact : " + contact)
            c_eqs = ds.get_contact_equation_list(device=device,
                                                 contact=contact)
            for ceq in c_eqs:
                print("\t\tContact Equation : " + ceq)
Esempio n. 3
0
def plot_band_diagram(device=None, regions=None, ec_name='EC', ev_name='EV'):
    if device is None:
        device = ds.get_device_list()[0]
    if regions is None:
        regions = ds.get_region_list(device=device)
    plt.figure(figsize=(6, 2.7))
    labels = []
    for region in regions:
        x = np.array(ds.get_node_model_values(device=device, region=region, name="x"))
        for band in [ec_name, ev_name]:
            band_edge = ds.get_node_model_values(device=device, region=region, name=band)
            plt.plot(x * 1e4, band_edge, marker='o', linestyle='-', markersize=3)
            labels.append(f'{band} in {region}')
    plt.legend(labels)
    plt.xlabel('x (µm)')
    plt.ylabel('Energy (eV)')
    plt.title('Band Diagram')
Esempio n. 4
0
def plot_potential(device=None, regions=None, potential='Potential'):
    if device is None:
        device = ds.get_device_list()[0]
    if regions is None:
        regions = ds.get_region_list(device=device)
    plt.figure()
    pots = np.array([])
    total_x = np.array([])
    for region in regions:
        x = np.array(ds.get_node_model_values(device=device, region=region, name="x"))
        # print(var_name, min(x), max(x), min(x)*1e4, max(x)*1e4)
        total_x = np.append(total_x, x)
        new_pots = ds.get_node_model_values(device=device, region=region, name=potential)
        pots = np.append(pots, new_pots)
        plt.plot(x*1e4, new_pots, marker='o', linestyle='-', markersize=3)
    plt.legend(regions)
    # plt.plot(total_x*1e4, pots)
    plt.xlabel('X (um)')
    plt.ylabel('Potential (V)')
    plt.title(potential)
Esempio n. 5
0
    def solve(self, *args, **kwargs):
        for region in self.device.mesh.regions:
            log.info('Computing photogeneration for region: %s' % region)
            # Assume 1D for now
            nodes = ds.get_node_model_values(device=self.device.name,
                                             region=region,
                                             name='x')

            pg = np.zeros((len(nodes), len(self.light_source)), dtype=float)
            rfidx = RefractiveIndex(region.material)
            for idλ, λ in enumerate(self.light_source):
                # I know, using unicode names here is asking for trouble
                # ... but looks nice when using greek letters
                # TODO: compute the real reflection
                R = 0
                # λ is nm, but irradiance's units are W⋅m–2⋅nm–1
                P = self.light_source.irradiance(λ)
                Φ_0 = (P * λ * 1e-9 / PhysicalConstants.hc) * (1 - R)
                # α(λ)'s units are cm-1. But we use m
                α = rfidx.alpha(λ) * 1e+2
                # TODO: do not assume conversion efficiency is 100% (1 photon = 1EHP by now)
                η_g = 1.0

                # Debug
                print('\n' + '-' * 70)
                print('Photogeneration dump. Parameters:')
                print(
                    'λ={:.2f} nm; P(λ)={:.2f}; Φ_0(λ)={:8.2e} m-2 s-1; α(λ)={:8.2e} m-1'
                    .format(λ, P, Φ_0, α))
                print('-' * 24)
                print('   x(μm)  |  G_op(x, λ)')
                print('-' * 24)
                for idx, x in enumerate(nodes):
                    pg[idx, idλ] = η_g * Φ_0 * exp(-α * x)
                    print('{:8.2f}  | {:8.2e}'.format(x * 1e6, pg[idx, idλ]))

            # Total photogeneration for each node
            # Conditions:
            #   100% quantum efficiency
            #   Ignoring reflection
            pgen_by_node = np.add.reduce(pg, 1)
            for i, v in enumerate(pgen_by_node):
                ds.set_node_value(device=self.device.name,
                                  region=region,
                                  name='G_op',
                                  index=i,
                                  value=float(v))
        if 'type' in kwargs:
            ds.solve(**kwargs)
        else:
            ds.solve(type='dc', **kwargs)
Esempio n. 6
0
def get_ds_status(short=True):
    """
    Prints the status of the current devsim setup and all variables, solutions, node models and edge models
    :return:
    """
    for device in ds.get_device_list():
        print("Device: " + device)
        for region in ds.get_region_list(device=device):
            print("\tRegion :" + region)
            params = ds.get_parameter_list(device=device, region=region)
            for param in params:
                val = ds.get_parameter(device=device,
                                       region=region,
                                       name=param)
                print(f"\t\t{param} = {val}")
            for node_model in ds.get_node_model_list(device=device,
                                                     region=region):
                nmvals = ds.get_node_model_values(device=device,
                                                  region=region,
                                                  name=node_model)
                nmstr = ','.join([f'{val:.3g}' for val in nmvals])
                print(f"\t\tNode Model '{node_model}' = {nmstr!s}")
            e_models = ds.get_edge_model_list(device=device, region=region)
            for edge_model in e_models:
                emvals = ds.get_edge_model_values(device=device,
                                                  region=region,
                                                  name=edge_model)
                emstr = ','.join([f'{val:.3g}' for val in emvals])
                print(f"\t\tEdge Model '{edge_model}' = {emstr}")
        for interface in ds.get_interface_list(device=device):
            print("\tInterface: " + interface)
            for imodel in ds.get_interface_model_list(device=device,
                                                      interface=interface):
                intstr = ','.join([
                    f'{val:.3g}' for val in ds.get_interface_model_values(
                        device=device, interface=interface, name=imodel)
                ])
                print(f"\t\tInterface Model: '{imodel}' = {intstr}")
            for ieq in ds.get_interface_equation_list(device=device,
                                                      interface=interface):
                # comm = ds.get_interface_equation_command(device=device, interface=interface, name=ieq)
                print(f"\t\tInterface Equation: {ieq}")
        contacts = ds.get_contact_list(device=device)
        for contact in contacts:
            print("\tContact : " + contact)
            c_eqs = ds.get_contact_equation_list(device=device,
                                                 contact=contact)
            for ceq in c_eqs:
                print("\t\tContact Equation : " + ceq)
Esempio n. 7
0
    def test_node_model(self):
        # Define mesh (default units are micrometers)
        mesh = Mesh('Test Mesh')
        mesh.add_line(0.0, 0.01, 'left')
        mesh.add_line(10.0, 1.0, 'right')
        mesh.add_contact(name='left',
                         tag='left',
                         material=materials.Metals.generic)
        mesh.add_contact(name='right',
                         tag='right',
                         material=materials.Metals.generic)
        mesh.add_region(name='Bulk',
                        material=materials.Silicon(),
                        tag1='left',
                        tag2='right')

        mesh.finalize()

        class SolarCell(Device):
            def __init__(self, name=None, mesh=None):
                super(SolarCell, self).__init__(name, mesh)
                # This is specific to this device
                self.set_node_model('Bulk', 'Acceptors',
                                    '1.0e16*step(0.5e-5-x)')
                self.set_node_model('Bulk', 'Donors', '1.0e18*step(x-0.5e-5)')
                self.set_node_model('Bulk', 'NetDoping', 'Donors-Acceptors')

        scell = SolarCell('MySolarCell', mesh=mesh)

        # Stablish conditions (light)
        # Setup the model
        from devsim.materials.light_sources import AM0
        from devsim.models import BeerLambertModel
        mdl = BeerLambertModel(scell, AM0(samples=25))
        scell.setup_model(mdl)
        # Solve
        scell.initial_solution('Bulk')
        scell.solve(type="dc",
                    absolute_error=1.0,
                    relative_error=1e-10,
                    maximum_iterations=30)
        scell.export('scell.dat')

        # Check results
        results = [
            n for n in get_node_model_values(
                device=scell.name, region=scell.mesh.regions[0], name='G_op')
        ]
        self.assertEqual(len(results), 47)
Esempio n. 8
0
    # PrintCurrents(device, "bot")
    tot_top, tot_bot = get_total_current(device)
    top_currents.append(tot_top)
    bot_currents.append(tot_bot)
    print(f"Total top: {tot_top:.2E} and total bottom: {tot_bot:.2E}")
    # bias_volt += 0.1
    # v += 1
# plt.plot(volt_sweep, top_currents)
# plt.plot(volt_sweep, bot_currents)
plt.semilogy(volt_sweep,
             np.abs(np.array(top_currents) - np.array(bot_currents)))
plt.show()

write_devices(file="boring diode.dat", type="tecplot")

x = get_node_model_values(device=device, region=region, name="x")
ymax = 10
ymin = 10
fields = ("Electrons", "Holes", "Donors", "Acceptors")
for i in fields:
    node_m_vals = get_node_model_values(device=device, region=region, name=i)
    if (max(node_m_vals) > ymax):
        ymax = max(node_m_vals)
    plt.semilogy(x, node_m_vals)
plt.xlabel('x (cm)')
plt.ylabel('Density (#/cm^3)')
plt.legend(fields)
ymax *= 10
plt.axis([min(x), max(x), ymin, ymax])
plt.savefig("diode_1d_density.png")
Esempio n. 9
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