2. Creating the FD-SOI Device
2.1. Requirements
2.1.1. Software components
QTCAD
2.1.2. Python script
qtcad/examples/practical_application/FDSOI/double_dot_fdsoi.py
2.1.3. References
2.2. Briefing
The file presented in this section is not meant to be run.
Instead, it contains quantities and a function that are imported by other
scripts in this practical application tutorial series.
In particular, the function get_double_dot_fdsoi defined here is used to
create the FD-SOI Device object.
This function is analogous to the identically named function defined in
A double quantum dot device in a fully-depleted silicon-on-insulator transistor.
2.3. Header
We start by importing the necessary Python modules
import pathlib
import numpy as np
from qtcad.device import materials as mt
from qtcad.device import constants as ct
from qtcad.device.mesh3d import Mesh
from qtcad.device import Device
from qtcad.device.analysis import plot_slice
The modules imported above provide access to the different classes and
functions needed to define materials and
create QTCAD Mesh and
Device objects associated with the FD-SOI
structure.
2.4. Default values
We then define some default values that will be used in the different scripts.
# Default values
V_set = 1.25 # Default SET potential (V)
V_qubit = 0.75 # Default qubit potential (V)
scaling = 1e-9 # scaling factor for the mesh
These provide the default voltages to be applied to the single-electron
transistor (SET) and qubit gates (plunger_gate_1_bnd and
plunger_gate_2_bnd, respectively) and also define the length scale of the
mesh.
2.6. Creating the device
Finally, we define the function that creates and returns the FD-SOI device model.
# Function to create the FD-SOI device
def get_double_dot_fdsoi(mesh_file_name: str="refined_dqdfdsoi.msh",
V_set: float=V_set, V_qubit: float=V_qubit) -> Device:
"""Create a Device object for the FD-SOI structure.
Args:
V_set (float): Potential applied to the SET gate.
V_qubit (float): Potential applied to the qubit gate.
mesh_file_name (str): Filename of the mesh file.
Returns:
Device: The constructed Device object.
list[str]: List of region names associated with the SET.
list[str]: List of region names associated with the qubit quantum-dot.
"""
# Create the mesh
script_dir = pathlib.Path(__file__).parent.resolve()
path_mesh = script_dir / "meshes"
mesh_file = path_mesh / mesh_file_name
mesh = Mesh(scaling, mesh_file)
# Define the device object
dvc = Device(mesh, conf_carriers='e')
dvc.set_temperature(0.1)
# Create the regions
dvc.new_region("oxide", mt.SiO2)
dvc.new_region("oxide.QD1", mt.SiO2)
dvc.new_region("oxide.QD2", mt.SiO2)
dvc.new_region("channel", mt.Si)
dvc.new_region("channel.QD1", mt.Si)
dvc.new_region("channel.QD2", mt.Si)
dvc.new_region("source", mt.Si, ndoping=1e20*1e6)
dvc.new_region("drain", mt.Si, ndoping=1e20*1e6)
# Set up boundary conditions
Ew = mt.Si.Eg/2 + mt.Si.chi # Midgap
dvc.new_gate_bnd("barrier_gate_1_bnd", 0.5, Ew)
dvc.new_gate_bnd("plunger_gate_1_bnd", V_set, Ew)
dvc.new_gate_bnd("barrier_gate_2_bnd", 0.5, Ew)
dvc.new_gate_bnd("plunger_gate_2_bnd", V_qubit, Ew)
dvc.new_gate_bnd("barrier_gate_3_bnd", 0.5, Ew)
dvc.new_ohmic_bnd("source_bnd")
dvc.new_ohmic_bnd("drain_bnd")
dvc.new_frozen_bnd("back_gate_bnd", -0.5, mt.Si, 1e15*1e6,
"n", 46*1e-3*ct.e)
# Create the double quantum dot region
SET_region_list = ["oxide.QD1", "channel.QD1"]
qubit_region_list = ["oxide.QD2", "channel.QD2"]
return dvc, SET_region_list, qubit_region_list
This function starts by generating the Mesh
object using the specified mesh file.
It then creates an instance of the Device class
and sets up the material stack of the device by defining the different regions
and assigning them appropriate materials.
Next, it applies appropriate boundary conditions to the surfaces representing
the gate contacts.
The plunger-gate voltages are set according to the function arguments.
In contrast, barrier-gate voltages are all set to a value of
\(0.5\,\mathrm{V}\).
This value of barrier-gate voltage was shown in Tunnel coupling in a double quantum dot in FD-SOI—Part 2: Tuning the barrier gate to
lead to minimal tunneling between different regions of the device, allowing
the quantum dots to be well-defined and isolated.
Finally, the get_double_dot_fdsoi function creates lists identifying the
SET region and the qubit region that will later be used when solving the
Schrödinger equation before returning the created
Device object along with these lists.
Note
In the next section of the practical application
(Simulating electrostatics using the linear Poisson solver), we import get_double_dot_fdsoi to
construct the FD-SOI device model passed to the linear Poisson
Solver to solve the linear
Poisson equation.
Because the linear Poisson
Solver neglects free carriers,
the doped "source" and "drain" regions do not contribute any mobile
charge to the solution, and therefore their doping has little practical
effect in this context.
We nevertheless keep the doping definitions here so the same function can
be reused to generate a device model for the nonlinear Poisson
Solver, which does include free
carriers.
For an example where the doping becomes relevant, see
Tunnel coupling in a double quantum dot in FD-SOI—Part 1: Plunger gate tuning.
2.7. Full code
__copyright__ = "Copyright 2022-2025, Nanoacademic Technologies Inc."
import pathlib
import numpy as np
from qtcad.device import materials as mt
from qtcad.device import constants as ct
from qtcad.device.mesh3d import Mesh
from qtcad.device import Device
from qtcad.device.analysis import plot_slice
# Default values
V_set = 1.25 # Default SET potential (V)
V_qubit = 0.75 # Default qubit potential (V)
scaling = 1e-9 # scaling factor for the mesh
# Visualization parameters
normal = (0., 0., 1.) # the plane of the slice is normal to the z axis
origin = (0., 0., -1. * scaling) # the slice is inside the Si quantum well
def save_slice(device: Device, data: np.ndarray, file_name: str, label: str) -> None:
"""Helper function to save a slice of the device data.
Args:
device (Device): The Device object containing the data.
data (np.ndarray): The data array to be sliced and saved.
file_name (str): The filename to save the slice plot.
label (str): The label for the colorbar axis.
"""
plot_slice(device.mesh, data, normal=normal, origin=origin, cb_axis_label=label,
path=file_name, show_figure=False)
# Function to create the FD-SOI device
def get_double_dot_fdsoi(mesh_file_name: str="refined_dqdfdsoi.msh",
V_set: float=V_set, V_qubit: float=V_qubit) -> Device:
"""Create a Device object for the FD-SOI structure.
Args:
V_set (float): Potential applied to the SET gate.
V_qubit (float): Potential applied to the qubit gate.
mesh_file_name (str): Filename of the mesh file.
Returns:
Device: The constructed Device object.
list[str]: List of region names associated with the SET.
list[str]: List of region names associated with the qubit quantum-dot.
"""
# Create the mesh
script_dir = pathlib.Path(__file__).parent.resolve()
path_mesh = script_dir / "meshes"
mesh_file = path_mesh / mesh_file_name
mesh = Mesh(scaling, mesh_file)
# Define the device object
dvc = Device(mesh, conf_carriers='e')
dvc.set_temperature(0.1)
# Create the regions
dvc.new_region("oxide", mt.SiO2)
dvc.new_region("oxide.QD1", mt.SiO2)
dvc.new_region("oxide.QD2", mt.SiO2)
dvc.new_region("channel", mt.Si)
dvc.new_region("channel.QD1", mt.Si)
dvc.new_region("channel.QD2", mt.Si)
dvc.new_region("source", mt.Si, ndoping=1e20*1e6)
dvc.new_region("drain", mt.Si, ndoping=1e20*1e6)
# Set up boundary conditions
Ew = mt.Si.Eg/2 + mt.Si.chi # Midgap
dvc.new_gate_bnd("barrier_gate_1_bnd", 0.5, Ew)
dvc.new_gate_bnd("plunger_gate_1_bnd", V_set, Ew)
dvc.new_gate_bnd("barrier_gate_2_bnd", 0.5, Ew)
dvc.new_gate_bnd("plunger_gate_2_bnd", V_qubit, Ew)
dvc.new_gate_bnd("barrier_gate_3_bnd", 0.5, Ew)
dvc.new_ohmic_bnd("source_bnd")
dvc.new_ohmic_bnd("drain_bnd")
dvc.new_frozen_bnd("back_gate_bnd", -0.5, mt.Si, 1e15*1e6,
"n", 46*1e-3*ct.e)
# Create the double quantum dot region
SET_region_list = ["oxide.QD1", "channel.QD1"]
qubit_region_list = ["oxide.QD2", "channel.QD2"]
return dvc, SET_region_list, qubit_region_list