nanotune.model.capacitancemodel
- class nanotune.model.capacitancemodel.CapacitanceModel(name: str, charge_nodes: Optional[Dict[int, str]] = None, voltage_nodes: Optional[Dict[int, str]] = None, N: Optional[Sequence[int]] = None, V_v: Optional[Sequence[float]] = None, C_cc_off_diags: Optional[Sequence[float]] = None, C_cv: Optional[Sequence[Sequence[float]]] = None, db_name: str = 'capa_model_test.db', db_folder: str = '.')[source]
Bases:
Instrument
Implementation of a general capacitance model with an arbitrary number of dots and gates. It simulates weakly coupled quantum dots with well localized charges and is a classical description based on two assumptions: (1) Coulomb interactions between electrons on dots and in reservoirs are parametrized by constant capacitances. (2) The single-particle energy-level spectrum is considered independent of electron interactions and the number of electrons, meaning that quantum mechanical energy spacings are not taken into account. The system of electrostatic gates, dots and reservoirs is represented by a system of conductors connected via resistors and capacitors.
Being based on https://journals.aps.org/rmp/abstract/10.1103/RevModPhys.75.1, the implementation uses the same terminology including charge and voltage nodes, representing quantum dots and electrostatic gates respectively, and electron and hole triple points.
The capacitor connecting node \(j\) and node \(k\) has a capacitance \(C_{jk}\) and stores a charge \(q_{jk}\). We distinguish between charge and voltage sub-systems, and thus their respective sub-matrices:
\mathbf{C} := \begin{pmatrix} \mathbf{C_{cc}} & \mathbf{C_{cv}} \ \mathbf{C_{vc}} & \mathbf{C_{vv}} \end{pmatrix}Diagonal elements of the capacitance matrix, \(C_{jj}\), are total capacitances of each node and carry the opposite sign of the matrix’s off-diagonal elements. The off-diagonal elements of \(\mathbf{\mathbf{C_{cc}}}\) are capacitances between charge nodes, while the off-diagonal elements of \(\mathbf{\mathbf{C_{vv}}}\) are capacitances between voltage nodes. The elements of \(\mathbf{\mathbf{C_{cv}}}\) are capacitances between voltage and charge nodes, and allow to calculate so-called virtual gate coefficients - useful knobs in semiconductor qubit experiments.
- snapshot_base(update: Optional[bool] = True, params_to_skip_update: Optional[Sequence[str]] = None) Dict[Any, Any] [source]
Pass on QCoDeS snapshot.
- set_voltage(n_index: int, value: float, node_type: str = 'voltage') None [source]
Convenience method to set voltages.
- Parameters
n_index – Index of node to set.
value – Value to set.
node_type – Which node type to set, either ‘voltage’ or ‘charge’.
- set_capacitance(which_matrix: str, indices: List[int], value: float) None [source]
Convenience function to set capacitances.
- Parameters
which_matrix – String identifier of matrix to set. Either ‘cv’ or ‘cc’.
indices – Indices of capacitances within the matrix.
value – Capacitance value to set.
- set_Ccv_from_voltage_distance(voltage_node_idx: int, dV: float, charge_node_idx: int) None [source]
Implements relation between voltage differences and capacitances between charge and voltage nodes.
- Parameters
voltage_node_idx – Voltage node index.
dV – Voltage difference between two charge transitions.
charge_node_idx – Charge node index.
- compute_energy(N: Optional[Sequence[int]] = None, V_v: Optional[Sequence[float]] = None) float [source]
Computes the total energy of the dot system.
- Parameters
N – charge configuration, i.e. number of charges on each charge node.
V_v – Voltages to set on voltages nodes.
- Returns
float – energy of the system
- determine_N(V_v: Optional[Sequence[float]] = None) List[int] [source]
Determines the charge state N by minimizing the total energy of the dot system.
- Parameters
V_v – Voltages to set on voltages nodes.
- Returns
list – Charge state, i.e. number of electrons on each charge node.
- get_triplepoints(voltage_node_idx: Sequence[int], N_limits: Sequence[Tuple[int, int]]) Tuple[ndarray[Any, dtype[float64]], ndarray[Any, dtype[float64]], List[List[int]]] [source]
Calculates triple points for charge configurations within ‘N_limits’.
- Parameters
voltage_node_idx – indices of gates to sweep
N_limit – Min and max values of number of electrons in each dot, defining all charge configurations to consider
- Returns
Coordinates of electron triple points np.array: Coordinates of hole triple points list: List of electron charge configurations
- Return type
np.array
- calculate_triplepoints(voltage_node_idx: Sequence[int], N: Sequence[int]) Tuple[ndarray[Any, dtype[float64]], ndarray[Any, dtype[float64]]] [source]
Determines coordinates in voltage space of triple points (electron and hole) for a single charge configuration.
- Parameters
voltage_node_idx – Indices of voltage nodes to be determined
N – Charge configuration, number of electrons of each charge node.
- Returns
Coordinates of electron triple points. np.array: Coordinates of hole triple points.
- Return type
np.array
- mu_electron_triplepoints(new_voltages: Sequence[float], voltage_node_idx: Sequence[int], N: Optional[Sequence[int]] = None) ndarray[Any, dtype[float64]] [source]
Calculates chemical potentials of all charge nodes for a given charge configuration N and corresponding to electron triple points (\(\mu(N)\)).
- Parameters
new_voltages – Voltages to set on voltage nodes.
voltage_node_idx – Voltage node indices to which the values in new_voltages correspond to.
N – Desired charge configuration, optional. If none supplied self.N() is taken.
- Returns
np.array – Chemical potentials of electron triple points corresponding to electron triple points.
- mu_hole_triplepoints(new_voltages: Sequence[float], voltage_node_idx: Sequence[int], N: Optional[Sequence[int]] = None) ndarray[Any, dtype[float64]] [source]
- Calculates chemical potentials of all charge nodes
for given charge configuration N and corresponding to hole triple points (\(mu_{j}(N + \hat{e}_{i})\)).
- Parameters
new_voltages – values of new gate voltages, to be replaced in self.V_v. These are the values scipy.optimize.fsolve is solving for.
voltage_node_idx – Voltages nodes indices to which the values above correspond to.
N – Desired charge configuration, if none supplied self.N() is taken.
- mu(dot_indx: int, N: Optional[Sequence[int]] = None, V_v: Optional[Sequence[float]] = None) float [source]
Calculates the chemical potential of a single dot (charge node) given the charge and voltage configuration of the entire dot system (all dots included).
- Parameters
dot_indx – index of dot for which the chemical potential should be computed.
N – Charge configuration of the entire system, i.e. the number of electrons on each charge node.
V_v – Voltages to set on (all) voltage nodes.
- Returns
float – Chemical potential of dot dot_indx.
- sweep_voltages(voltage_node_idx: Sequence[int], voltage_ranges: Sequence[Tuple[float, float]], n_steps: Sequence[int] = [50, 50], line_intensity: float = 1.0, add_noise: bool = True, target_snr_db: float = 100, normalize: bool = True, known_regime: str = 'doubledot', known_quality: Optional[int] = None, add_charge_jumps: bool = False, jump_freq: float = 0.001) Optional[int] [source]
Sweep two voltage nodes to measure a charge diagram. Calculate current at zero bias and at zero temperature. Random normal noise and charge jumps can be added optionally as well. The diagram is saved into .db using QCoDeS.
- Parameters
voltage_node_idx – Voltage node indices to sweep.
voltage_ranges – Voltage ranges to sweep.
n_steps – Number of steps of the measurement.
line_intensity – Multiplication factor of transport current. It depends on number of degeneracies and coupling strength between dots and leads.
add_noise – whether or not to add noise.
broadening – level broadening due to dots coupling to leads
target_snr_db – Target signal-to-noise ratio used to calculate amplitude of random normal noise.
normalize – whether to normalize the data.
known_regime – Label to be saved in metadata.
known_quality – Quality to be saved in metadata.
add_charge_jumps – Whether or not to add random charge jumps.
jump_freq – Average frequency at which optional charge jumps should occur.
- Returns
int – QCoDeS data run ID
- sweep_voltage(voltage_node_idx: int, voltage_range: Sequence[float], n_steps: int = 100, line_intensity: float = 1.0, add_noise: bool = True, broadening: float = 0.01, target_snr_db: float = 100.0, normalize: bool = True) Optional[int] [source]
Sweep one voltage to measure Coulomb oscillations. Calculate current at zero bias and at zero temperature. Random normal noise and charge jumps can be added optionally as well. The diagram is saved into .db using QCoDeS.
- Parameters
voltage_node_idx – voltage node index to sweep.
voltage_range – Voltage range to sweep.
n_steps – Number of steps of the measurement.
line_intensity – Multiplication factor of transport current. It depends on number of degeneracies and coupling strength between dots and leads.
add_noise – whether or not to add noise.
broadening – level broadening due to dots coupling to leads
target_snr_db – target signal-to-noise ratio used to calculate amplitude of random normal noise.
normalize – whether to normalize the data.
- Returns
int – QCoDeS data run ID.
- sweep_bias_and_voltage(voltage_node_idx: int, voltage_range: Sequence[float], bias_range: Tuple[float, float], n_steps: Sequence[int] = [50, 50], line_intensity: float = 1.0) Tuple[ndarray[Any, dtype[float64]], ndarray[Any, dtype[float64]]] [source]
Computes a Coulomb diamond diagram by sweeping the source-drain bias against a voltage. It returns two diagrams, one showing the bias-voltage sweep without co-tunneling events and a second showing elastic co-tunneling events only, calculated via get_co_tunneling_rate.
- Parameters
voltage_node_idx – voltage node index to sweep.
voltage_range – range of voltage to sweep.
bias_range – bias range to sweep.
n_steps – number of steps in each dimension.
line_intensity – Multiplication factor of number of degeneracies, resulting in the desired peak hight before normalization.
- Returns
np.ndarray – 2d diagram of bias-voltage sweep without tunneling events.
np.ndarray – 2d diagram showing elastic co-tunneling only.
- get_co_tunneling_rate(bias: float, mu_n: float, mu_n_plus_one: float, source_rate_N: float = 0.3, source_rate_N_plus_one: float = 0.2, drain_rate_N: float = 0.3, drain_rate_N_plus_one: float = 0.2, h_bar: float = 1) float [source]
Calculates the elastic co-tunneling rate according to the equation on page 400 (chapter 8) or Thomas Ihn’s book. This equations assumes the system to be at zero temperature and that tunneling rates are independent of energy over a small source-drain voltage.
- Parameters
bias – source drain bias
mu_n – chemical potential of charge state with a total of N charges, e.g. of the self.N() state.
mu_n_plus_one – chemical potential of charge state with N+1 charges, e.g. an adjacent charge state of self.N(). Adjacent means having one additional charge.
source_rate_N – tunneling rate between source and a dot system in charge state with a total of N charges.
source_rate_N_plus_one – tunneling rate between source and a dot system in charge state with a total of N+1 charges.
drain_rate_N – tunneling rate between drain and a dot system in charge state with a total of N charges
drain_rate_N_plus_one – tunneling rate between drain and a dot system in charge state with a total of N+1 charges.
h_bar – Plank constant or the substitution thereof.
- Returns
float – co-tunneling rate
- calculate_transport_at_zero_bias(N_current: Optional[Sequence[int]] = None, V_v: Optional[Sequence[float]] = None, broadening: float = 0.01) float [source]
Computes transport signal at zero bias and at zero temperature.
Assume the electrochemical potentials of source and drain to be zero (zero bias) Transport current is propotional to DOS (density of states) of all dot levels at energy 0 Assume that all dots are connected sequentially, meaning carrier needs to hop from source to dot 1, then to dot 2, …, then to dot N, and finally hop to drain In this case, current is propotional to (DOS of dot 1 at energy 0) * … * (DOS of dot N at 0) For each dot, only consider current charge state and the first excited state. Also take into account level broadening due to dots coupling to leads.
- Parameters
N_current – charge state to which other states differing by at most one charge should be compared to. Default is self.N().
V_v – voltage configuration at which the energies should be computed. Default is self.V_v().
broadening – level broadening due to dots coupling to leads
- Returns
float – transport signal in given configuration
- lorentzian_density_of_state(transport_energy: float, level_energy: float, broadening: float) float [source]
Computes density of states of a energy level at given transport energy using a Lorentzian function
For reference, see equation 1.3.2 in S. Datta’s book Quantum Transport Atom To Transistor
- Returns
float – density of state at transport energy
- get_energy_differences_to_adjacent_charge_states(N_current: Optional[Sequence[int]] = None, V_v: Optional[Sequence[float]] = None) ndarray[Any, dtype[float64]] [source]
Computes energy differences between a charge state and all states differing from it by at most one charge.
- Parameters
N_current – charge state to which other states differing by at most one charge should be compared to. Default is self.N().
V_v – voltage configuration at which the energies should be computed. Default is self.V_v().
- Returns
np.array – Energy differences to charge states differing by at most one charge.
- get_energy_differences_to_excited_charge_states(N_current: Optional[Sequence[int]] = None, V_v: Optional[Sequence[float]] = None, n_diff_charges: int = 3) ndarray[Any, dtype[float64]] [source]
Computes energy differences between a charge state and all states differing from it by at most ‘n_diff_charges’ charges. These additional charges represent excited charge state which require an excitation voltage for a quantum dot system to reach them.
- Parameters
N_current – charge state to which other states differing by at most ‘n_diff_charges’ charges should be compared to. Default is self.N().
V_v – voltage configuration at which the energies should be computed. Default is self.V_v().
n_diff_charges – number of extra charges to consider adding to ‘N_current’.
- Returns
np.array – Energy differences to charge states differing by at most ‘n_diff_charges’ charges.
- determine_sweep_voltages(voltage_node_idx: Sequence[int], V_v: Optional[Sequence[float]] = None, N_limits: Optional[Sequence[Tuple[int, int]]] = None) List[List[float]] [source]
Determines voltages to sweep to measure specific charge transitions.
- Parameters
voltage_node_idx – Indices of voltages nodes to sweep.
V_v – Voltage configuration of all gates.
N_limits – Charge configuration ranges to measure. E.g. for a double dot to sweep over empty dots to both having 3 electrons: [(0, 3), (0, 3)]
- Returns
list – Nested list of voltages limits to sweep. Example double dot: [[gate1_min_voltage, gate1_max_voltage], [gate2_min_voltage, gate2_max_voltage]]