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]]