Examples
All examples are available as Jupyter notebooks in examples/notebooks/.
Each notebook can be run on nanoHUB or locally with PADRE installed.
Jupyter Notebooks
# |
Notebook |
Description |
|---|---|---|
00 |
|
Overview and setup |
01 |
|
Component-by-component tour of the API |
02 |
|
I-V characteristics, band diagrams, ideality factor |
03 |
|
Schottky barrier, forward/reverse I-V, workfunction effects |
04 |
|
Transfer and output characteristics, threshold voltage |
05 |
|
Gummel plot, β extraction, common-emitter output curves |
06 |
|
C-V analysis, band bending, single- and double-gate configurations |
07 |
|
Output and transfer characteristics, doping and workfunction effects |
Using Device Factory Functions
The simplest workflow uses factory functions that handle mesh, regions, doping, contacts, materials, and solve commands automatically:
from nanohubpadre import create_mos_capacitor
sim = create_mos_capacitor(
oxide_thickness=0.1,
silicon_thickness=5.0,
substrate_doping=1e15,
substrate_type="p",
gate_type="n_poly",
log_cv=True,
log_cv_lf=True,
log_bands_eq=True,
log_profiles_eq=True,
vg_sweep=(-3.0, 5.0, 0.08),
)
result = sim.run()
if result.returncode != 0:
raise RuntimeError(f"Simulation failed:\n{result.stderr}")
# All visualization through sim methods — no manual parsing
sim.plot_band_diagram(suffix="eq")
sim.plot_carriers(suffix="eq", log_scale=True)
sim.plot_electrostatics(suffix="eq")
sim.plot_cv()
MOS Capacitor (Rappture Reference)
The following reproduces the nanoHUB MOSCap Rappture tool defaults exactly.
from nanohubpadre import create_mos_capacitor
sim = create_mos_capacitor(
oxide_thickness=0.1, # 100 nm (Rappture default)
ny_oxide=100,
silicon_thickness=5.0,
ny_silicon=200,
substrate_doping=1e15, # Na = 1e15 /cm³
substrate_type="p",
gate_type="n_poly", # n+ poly silicon gate
oxide_permittivity=3.9,
taun0=1e-9, # 1 ns carrier lifetimes
taup0=1e-9,
temperature=300,
log_cv=True,
cv_file="cv_hf",
ac_frequency=1e6, # HF: 1 MHz
log_cv_lf=True,
cv_lf_file="cv_lf",
ac_frequency_lf=1.0, # LF: 1 Hz
log_bands_eq=True,
log_qf_eq=True,
log_profiles_eq=True,
vg_sweep=(-3.0, 5.0, 0.08), # -3V to +5V, 100 steps
)
result = sim.run()
if result.returncode != 0:
raise RuntimeError(f"Simulation failed:\n{result.stderr}")
sim.plot_band_diagram(suffix="eq", title="Band Diagram at Equilibrium (Vg=0)")
sim.plot_carriers(suffix="eq", log_scale=True)
sim.plot_electrostatics(suffix="eq")
sim.plot_cv(title="MOS Capacitor C-V (HF 1 MHz + LF 1 Hz)")
Double-Gate MOS Capacitor
from nanohubpadre import create_mos_capacitor
sim = create_mos_capacitor(
oxide_thickness=0.005,
silicon_thickness=0.02,
substrate_doping=1e17,
substrate_type="p",
gate_type="n_poly",
gate_config="double",
back_oxide_thickness=0.005,
back_gate_type="n_poly",
log_cv=True,
log_bands_eq=True,
vg_sweep=(-2.0, 2.0, 0.1),
)
result = sim.run()
if result.returncode != 0:
raise RuntimeError(f"Simulation failed:\n{result.stderr}")
sim.plot_band_diagram(title="Double-Gate — Equilibrium")
sim.plot_cv(title="Double-Gate C-V")
PN Diode
from nanohubpadre import create_pn_diode
sim = create_pn_diode(
length=2.0,
p_doping=1e17,
n_doping=1e17,
temperature=300,
log_iv=True,
forward_sweep=(0.0, 1.0, 0.05),
log_bands_eq=True,
)
result = sim.run()
if result.returncode != 0:
raise RuntimeError(f"Simulation failed:\n{result.stderr}")
sim.plot_iv(title="PN Diode I-V", log_scale=True)
sim.plot_band_diagram(title="PN Diode Band Diagram")
MOSFET
from nanohubpadre import create_mosfet
sim = create_mosfet(channel_length=0.025, device_type="nmos")
result = sim.run()
if result.returncode != 0:
raise RuntimeError(f"Simulation failed:\n{result.stderr}")
sim.plot_transfer(gate_electrode=3, drain_electrode=2,
title="NMOS Transfer Characteristic")
Low-Level (Manual) Example
For full control over the device structure, build the simulation from scratch:
1#!/usr/bin/env python3
2"""
3Python equivalent of moscap.in for PADRE simulation.
4
5This script generates the same PADRE input deck as moscap.in
6MOS Capacitor structure with oxide-silicon-oxide
7"""
8
9from nanohubpadre import (
10 Simulation, Mesh, Region, Electrode, Doping, Contact,
11 Material, Models, System, Solve, Log, Plot1D
12)
13
14
15def create_moscap_simulation():
16 """Create the MOS capacitor simulation equivalent to moscap.in"""
17
18 sim = Simulation()
19
20 # Mesh Specification
21 sim.mesh = Mesh(nx=3, ny=41)
22 sim.mesh.add_y_mesh(1, 0)
23 sim.mesh.add_y_mesh(10, 0.002, ratio=0.8)
24 sim.mesh.add_y_mesh(21, 0.032, ratio=1.25)
25 sim.mesh.add_y_mesh(31, 0.062, ratio=0.8)
26 sim.mesh.add_y_mesh(41, 0.064, ratio=1.25)
27 sim.mesh.add_x_mesh(1, 0.001)
28 sim.mesh.add_x_mesh(3, 1, ratio=1)
29
30 # Regions specification
31 sim.add_region(Region(1, ix_low=1, ix_high=3, iy_low=1, iy_high=10,
32 material="sio2", insulator=True))
33 sim.add_region(Region(2, ix_low=1, ix_high=3, iy_low=10, iy_high=31,
34 material="silicon", semiconductor=True))
35 sim.add_region(Region(3, ix_low=1, ix_high=3, iy_low=31, iy_high=41,
36 material="sio2", insulator=True))
37
38 # Electrodes specification
39 sim.add_electrode(Electrode(1, ix_low=1, ix_high=3, iy_low=1, iy_high=1))
40 sim.add_electrode(Electrode(2, ix_low=1, ix_high=3, iy_low=41, iy_high=41))
41
42 # Doping specification
43 sim.add_doping(Doping(region=2, p_type=True, concentration=1e18, uniform=True))
44
45 # Contact specification
46 sim.add_contact(Contact(all_contacts=True, neutral=True))
47 sim.add_contact(Contact(number=1, n_polysilicon=True))
48 sim.add_contact(Contact(number=2, n_polysilicon=True))
49
50 # Material lifetime specification
51 sim.add_material(Material(name="silicon"))
52 sim.add_material(Material(name="sio2", permittivity=3.9, qf=0))
53
54 # Specify models
55 sim.models = Models(temperature=300, conmob=True, fldmob=True)
56 sim.system = System(electrons=True, holes=True, newton=True)
57
58 # Solve for initial conditions
59 sim.add_solve(Solve(initial=True))
60 sim.add_command(Plot1D(potential=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
61 ascii=True, outfile="pot"))
62 sim.add_command(Plot1D(qfn=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
63 ascii=True, outfile="qfn"))
64 sim.add_command(Plot1D(qfp=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
65 ascii=True, outfile="qfp"))
66 sim.add_command(Plot1D(band_val=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
67 ascii=True, outfile="val"))
68 sim.add_command(Plot1D(band_con=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
69 ascii=True, outfile="con"))
70 sim.add_command(Plot1D(electrons=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
71 ascii=True, outfile="ele"))
72 sim.add_command(Plot1D(holes=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
73 ascii=True, outfile="hole"))
74 sim.add_command(Plot1D(net_charge=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
75 ascii=True, outfile="ro"))
76 sim.add_command(Plot1D(e_field=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
77 ascii=True, outfile="efield"))
78
79 # Solve for applied bias
80 sim.add_solve(Solve(v1=0, vstep=-0.2, nsteps=10, electrode=[1, 2]))
81 sim.add_log(Log(acfile="ac"))
82 sim.add_solve(Solve(v1=-2.0, vstep=0.2, nsteps=20, electrode=[1, 2],
83 ac_analysis=True, frequency=1e7))
84 sim.add_log(Log(off=True))
85
86 # Final plots after bias
87 sim.add_command(Plot1D(potential=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
88 ascii=True, outfile="potiv"))
89 sim.add_command(Plot1D(qfn=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
90 ascii=True, outfile="qfniv"))
91 sim.add_command(Plot1D(qfp=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
92 ascii=True, outfile="qfpiv"))
93 sim.add_command(Plot1D(band_val=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
94 ascii=True, outfile="valiv"))
95 sim.add_command(Plot1D(band_con=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
96 ascii=True, outfile="coniv"))
97 sim.add_command(Plot1D(electrons=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
98 ascii=True, outfile="eleiv"))
99 sim.add_command(Plot1D(holes=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
100 ascii=True, outfile="holeiv"))
101 sim.add_command(Plot1D(net_charge=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
102 ascii=True, outfile="roiv"))
103 sim.add_command(Plot1D(e_field=True, y_start=0, y_end=0.064, x_start=0.5, x_end=0.5,
104 ascii=True, outfile="efieldiv"))
105
106 return sim
107
108
109if __name__ == "__main__":
110 sim = create_moscap_simulation()
111 deck = sim.generate_deck()
112 print(deck)
Running the Examples
To run a Python example script:
cd padre
PYTHONPATH=. python3 examples/moscap.py
To run a notebook on nanoHUB, upload it and select the PADRE kernel.
To run locally, ensure PADRE is in your PATH and start Jupyter:
jupyter notebook examples/notebooks/06_MOS_Capacitor.ipynb