qtcad.device.device module

Device objects and methods.

class Device(mesh=None, inp_dict=None, conf_carriers='unspecified', hole_kp_model=None)

Bases: _VisConvenienceMixin, Device

Device properties. All units are SI.

Attributes:
  • mesh (mesh object) – The mesh on which device properties are defined

  • boundaries (list) – List of boundary objects for the physical boundary conditions (Poisson’s equation).

  • bnd_schrod (list) – List of boundary objects for the physical boundary conditions (Schrodinger’s equation).

  • mc (1D field) – Density of states effective mass of electrons at each node. Rows: Elements Cols: Nodes

  • mv (2D field) – Density of states effective mass of holes at each node (1st index) and for each band (2nd index).

  • Me_inv (3D field) – Inverse effective mass tensor ():math:3     imes 3 array) for each element of the device.

  • g_star (float) – Effective electron g-factor (for device). One g-tensor for entire device - not position dependent. To get the associated g-tensor use get_electron_g_factor

  • hole_Zeeman_params (1D array) – 2 entries kappa and q. One set of ‘g-factors’ used for the entire device - not position dependent. The first entry is the kappa g-factor and the second is the q g-factor. To get the associated g-tensors use get_hole_Zeeman_params

  • B (2D field) – Magnetic field at each node of device.

  • hole_kp_model (string) – Function of k.p parameters to use to calculate the hole D matrix. Available values are: ‘luttinger_kohn_foreman’ and None.

  • electron_kp_model (ElectronKPModel or None) – Electron k·p model attached to the device. When present, the Schrödinger solver uses it to assemble the electron Hamiltonian.

  • electron_kp_params (dict[str, object]) – Stores the electron k·p parameters defined over the device. The keys are parameter names referenced by ElectronKPParameter objects, and the values are the corresponding coefficients, which can be stored as scalars, band matrices, or spatial callables.

  • D (5D field or None) – Hole D matrix if holes are considered. Default is None.

  • eps (1D field) – Permittivity at each node.

  • T (float) – Temperature

  • EF (float) – Fermi energy. Absolute value.

  • ND (1D field) – Density of donor impurities at each node.

  • NA (1D field) – Density of acceptor impurities at each node.

  • gD (int) – Donor level degeneracy.

  • gA (int) – Acceptor level degeneracy.

  • gc (1D field) – Total (spin and valley) conduction band degeneracy

  • gv (2D field) – Total valence band degeneracy for each node (1st index) and band (2nd index).

  • gqc (1D field) – Total degeneracy (spin and valley) of electrons to use when populating energy eigenstates. Default: 4, for spin degeneracy and two-fold valley degeneracy of the Delta_2 valley in silicon.

  • chi (1D field) – Semiconductor electron affinity at each node.

  • Eg (1D field) – Semiconductor bandgap at each node.

  • Ed (1D field) – Donor binding energy at each node.

  • Ea (1D field) – Acceptor binding energy at each node.

  • phi_F (float or 1D field) – Reference potential.

  • V (1D field) – Confinement potential at each node.

  • Vext (1D field) – External (offset) potential at each node. Used for heterostructures or for testing. An external potential is an additional potential accounted for only in the Schrodinger solver.

  • insulator (1D field) – Boolean (True of False) for each node. If True, then no carrier can be present at the corresponding node.

  • dot_region (list) – Submeshes or string labels defining the quantum dot region, in which confined carrier densities are set to zero in non-linear Poisson

  • dot_nodes (1D array or None) – Index of each global node belonging to the quantum dot region, where confined carrier densities are set to zero in non-linear Poisson.

  • dot_elems (1D array or None) – Index of each element belonging to the quantum dot region, where confined carrier densities are set to zero in non-linear Poisson.

  • n (1D field) – Total electron density at each node, including contributions from both classical semiconductor physics and quantum effects.

  • p (1D field) – Total hole density at each node, including contributions from both classical semiconductor physics and quantum effects.

  • nq (1D field) – Electron density at each node due to quantum effects, i.e., the solution of Schrodinger’s equation.

  • pq (1D field) – Hole density at each node due to quantum effects, i.e., the solution of Schrodinger’s equation.

  • Nplus (1D field) – Density of ionized donors.

  • Nminus (1D field) – Density of ionized acceptors.

  • rho (1D field) – Total charge density at each node (excluding contribution from any point charges [see rho_pc]).

  • rho_prime (1D field) – Derivative of the charge density with respect to electrostatic potential phi at each node.

  • rho_0 (field) – Background charge density.

  • rho_pc (field) – Charge density associated to point charges.

  • phi_pc (field) – Electric potential due only to the point charges.

  • point_charge_pos (list) – List of point charge positions.

  • point_charge_val (list) – List of point charge values.

  • point_charge_radius (float) – Radius of the point charges.

  • energies (1D array or None) – Eigen-energies of Schrodinger’s equation. For holes, the convention used is the one presented in QTCAD convention for holes.

  • eigenfunctions (2D field, 3D field or None) – Eigenfunctions of the Schrödinger equation. The array shape depends on whether a band index is present. Band indices are used for holes, or for electrons when spin and/or valley degrees of freedom are included. Shape conventions:

    • (N_nodes, N_levels) — No band index:
      • Axis 0: Global-node index.

      • Axis 1: Energy-level index.

    • (N_nodes, N_levels, N_bands) — With band index:
      • Axis 0: Global-node index.

      • Axis 1: Energy-level index.

      • Axis 2: Band index (encodes band, spin, and/or valley states).

    Band index ordering:
    • Holes:

      Band ordering follows the k·p model used. For more details on the conventions used for holes, see the QTCAD convention for holes.

    • Electrons with spin only:
      Band index runs over spin in the following order:
      • 0 → Spin up (along z-axis)

      • 1 → Spin down (along z-axis)

    • Electrons with valley only:

      Band index runs over valleys.

    • Electrons with both spin and valley:
      Band index runs over spin first and then valley, with ordering:
      • 0 → Valley 1, spin up

      • 1 → Valley 1, spin down

      • 2 → Valley 2, spin up

      • 3 → Valley 2, spin down

    None indicates that eigenfunctions were not computed or are unavailable.

  • macro_diff (1D field) – Difference between the macroscopic potential of the material and that of the reference material.

  • vlnce_band_macro (1D field) – Position of the valence band edge with respect to the macroscopic potential in the bulk material.

  • conf_carriers (str or None) – Which carrier densities from quantum-confined regions to add to the total charge density. Electrons: ‘electrons’ or ‘e’ Holes: ‘holes’ or ‘h’ Neither: None.

  • statistics (str) – Model to use for the carrier statistics. Maxwell-Boltzmann (‘MB’), Fermi-Dirac (‘FD’), or approximate Fermi-Dirac (‘FD_approx’). Default: ‘FD_approx’

  • ionization (str) – Dopant ionization model: ‘complete’ or ‘incomplete’.

  • coulomb_mat (4D array) – Coefficients \(V_{ijkl}\) of the Coulomb interaction in second quantization. Typically a 4D array, but can also be a 2D array when overlaps between basis states are neglected, in which case the array elements are related to the general 4D array by \(V_{ij} = V_{ijij}\).

  • many_body_subspaces (list of Subspace objects) – Subspace objects resulting from the many-body solver. The n-th element of the list contains information about the n-particle subspace.

  • chem_potentials (1D array) – Chemical potentials of the device (in Joules).

  • coulomb_peak_pos (1D array) – Coulomb peak positions for this device with respect to the reference gate potential (in volts).

  • zeeman (bool) – Whether or not Zeeman effects should be considered for the device

  • orb_B_effects (bool) – Whether or not orbital magnetic effects should be considered for the device

  • soc (3D array) – Describes the spin-orbit coupling in the system. The first index runs from 0 to 2 and describes coupling to the kx, ky, and kz operator respectively. The second and third indices run over the number of bands in the model. They define the matrices that are proportional to kx, ky, and kz for the specific type of spin-orbit coupling being considered.

  • region_idx (1D Field) – The region index of each element in the mesh. The region index is determined by the order in which each region was added to the device via the new_region method.

  • material_idx (1D Field) – The material index of each element in the mesh. The material index is determined by the order in which each material was added to the device via the new_region method.

Note

Default material values are for silicon. Electron affinity and bandgap are taken from http://www.virginiasemi.com/pdf/generalpropertiessi62002.pdf. Default donor (acceptor) binding energies are for phosphorus (boron).

__init__(mesh=None, inp_dict=None, conf_carriers='unspecified', hole_kp_model=None)

Constructor of the Device class.

Parameters:
  • mesh (mesh object, optional) – Mesh on which the device is defined. Default mesh if unspecified.

  • inp_dict (dict, optional) – Dictionary of device attributes. Every unspecified device attribute takes a default value instead.

  • conf_carriers (str or None, optional) – The type of charge carrier to be modeled quantum mechanically. Electrons (‘e’), holes (‘h’), or None’. Default: ‘unspecified’, in which case confined carriers are set to be electrons and a warning is raised.

  • hole_kp_model (string, optional) – The name of the k.p model to use for the holes. The string should be the name of a function in the kp module of the materials package (e.g., “luttinger_kohn_foreman” or “luttinger_kohn_foreman_6band”). Default: None, in which case the four-band “luttinger_kohn_foreman” model is used. A warning is raised in this case if conf_carriers is set to be holes. The hole_kp_model optional argument is only used for holes.

add_point_charges(pos: ndarray, val: float | ndarray, profile: callable | str = 'Gaussian', r: float | ndarray = 1e-10, closest_node: bool = False, refine: bool = True, refine_on_setup: bool = False, refinement_radius: float = 2.0) None

Adds point charges to the device.

Parameters:
  • pos (np.ndarray) – Locations of the point charges. The rows run over the point charges and the columns give the x, y, and z coordinates of the point charges.

  • val (float or np.ndarray) – The value of each point charge in SI units. If a single float is given, it is applied to all point charges. If an (1d) array is given, it must have the same number of entries as the pos array has rows. In this case, each entry sets the value of the point charge at the position of the corresponding row in pos.

  • profile (str or callable, optional) – The point charge is converted to a volume charge density. The charge can be taken to be ‘Gaussian’ distributed, ‘Uniform’ distributed, or ‘Exponential’ distributed. This can also be specified by a custum callable function. This callable should have 1 or 3 inputs. If there is only 1 input the point charge density profile is assumed to be isotropic and the input is taken to signify the distance from the point charge position. If there are 3 inputs, the inputs are taken to be the x, y, and z coordinates relative to the point charge position. Defaults to ‘Gaussian’.

  • r (float or np.ndarray, optional) – Radius of the sphere over which the point charges are spread. If a single float is given, it is applied to all point charges. If an (1d) array is given, it must have the same number of entries as the pos array has rows. In this case, each entry sets the radius of the point charge at the position of the corresponding row in pos. If profile is not a string, this argument is ignored. Defaults to 1e-10 (1 Angstrom).

  • closest_node (bool, optional) – Whether or not to shift the position of the point charges to the closest mesh node. Defaults to False.

  • refine (bool, optional) – Whether or not to refine the mesh around the point charges. Defaults to True.

  • refine_on_setup (bool, optional) – Whether or not to refine the mesh around the point charges when the device is set up (before any Poisson solver has been applied). If True, automatically sets refine = True. Defaults to False.

  • refinement_radius (float, optional) – The radius of the sphere around the point charges over which the mesh is refined [in units of r]. Defaults to 2.0.

add_to_V(V, region=None)

Add a constant potential to a given region

Parameters:
  • V (float) – Potential to be added.

  • region (string or None) – If string, adds V to the potential defined over the region

add_to_ref_potential(phi, region=None)

Adds a constant potential to the reference potential in a given region.

Parameters:
  • phi (float) – Potential to be added.

  • region (string or None, optional) – If string, adds phi to the reference potential defined over the region. If None, adds phi everywhere.

align_bands(ref_mat)

Sets the reference potential to be spatially dependent to have all bands aligned with respect to macroscopic potential parameters.

Parameters:

ref_mat (material object) – Reference material.

Note

See Band alignment from atomistic simulations.

While the reference potential \(\phi_F\) is chosen to correctly align the bands, the reference potential \(\phi_0^\mathrm{ref}\) is set to have \(e\phi_0^\mathrm{ref}\) equal to the intrinsic work function of the reference material at zero temperature.

assign_missing_properties()

Assigns silicon to any regions of the device that are currently undefined.

If this function is not called, a ValueError will be raised during device initialization if any undefined regions are detected.

band_weight()

Computes the eigenfunction probability density to be in each band. Only works when there are multiple bands in the model (e.g. holes or electrons with spin).

Returns:

2D array – Dimensions are number of eigenstates x bands. The entries contain the associated weights.

cond_band_edge()

Output conduction band edge at each mesh point.

Returns:

2d Field – The conduction band edge in Joules at each local node.

em_energy_per_elem(e: ndarray[float | complex128], b: ndarray[float | complex128]) ndarray[float]

Finds the time-averaged electromagnetic energy in each element for a given set of fields.

\[\frac14 \iint_{\Omega_e} \varepsilon \vec E^* \cdot \vec E + \frac14 \mu_0^{-1} \vec B^* \cdot \vec B dV.\]

where \(\vec E(\vec r)\) and \(\vec B(\vec r)\) are frequency-domain electric field and magnetic flux density, respectively.

Parameters:
  • e – array representing \(\vec E\) above. Indices run over (respectively) elements, local nodes, components.

  • b – array representing \(\vec B\) above. Indices run over (respectively) elements, local nodes, and components for 3D and elements and local nodes for 2D, where b represents the z component.

Returns:

Time-averaged electromagnetic energy in each element.

Note

In version 2.1.3, the definition of the output of this method has changed by a factor of 1/2. This note will be removed in version 2.3.

energy_b(b: ndarray[Shape2D | Shape3D | Shape4D, dtype[complex128]] | None = None, region: str | None = None, include_inductors: bool = False) float | ndarray[tuple[int], dtype[floating]]

Finds the time-averaged magnetic energy in a region or the entire device from the magnetic flux density.

Parameters:
  • b – If not None, this gives the frequency-domain magnetic flux density in the device.

    For 3D devices:

    The first three axes correspond to elements, then local nodes, then components.

    For 2D devices:

    The first two axes correspond to elements, then local nodes.

    The last optional axis can be used to represent the field for different modes.

    If None, the method assumes that one of the Maxwell solvers (driven or eigenmode) has been run and its result is used to find the energy.

  • region – String labeling the physical group of a region for which the energy is computed. If None, the energy is computed for the entire device.

  • include_inductors – If True, the result includes the energy stored in lumped inductors (created via new_inductor) and RLC ports with inductive component of the admittance (created via new_rlc_port). This option is only supported when b is None and region is None.

Returns:

Time-averaged magnetic energy given by

\[\int_{\Omega} \dfrac{\vec B^* \cdot \vec B}{4 \mu_0} d\Omega,\]

where \(\Omega\) is either the region or the entire device.

Note

In version 2.1.3, the definition of the output of this method has changed by a factor of 1/2. This note will be removed in version 2.3.

energy_b_elems(b: ndarray[Shape2D | Shape3D | Shape4D, dtype[complex128]]) ndarray[Shape1D | Shape2D, dtype[floating]]

Finds the time-averaged magnetic energy in each element from the magnetic flux density.

Parameters:

b – frequency-domain magnetic flux density in the device (z-component in 2D case). For 3D: Indices run over elements, then over local nodes,

then over components.

For 2D: Indices run over elements, then over local nodes. An optional last axis can be used for multiple modes.

Returns:

Array representing the time-averaged magnetic energy, given by

\[\int_{\Omega_e} \dfrac{\vec B^* \cdot \vec B}{4 \mu_0} d\Omega_e.\]

Indices run over elements. If an axis for modes is present, the last axis corresponds to the mode index.

Note

In version 2.1.3, the definition of the output of this method has changed by a factor of 1/2. This note will be removed in version 2.3.

energy_e(e: ndarray[Shape3D | Shape4D, dtype[complex128 | floating]] | None = None, region: str | None = None) float | Array1D[floating]

Finds the time-averaged electric energy in a region or the entire device from electric field.

Parameters:
  • e – If not None, this gives the frequency-domain electric field in the device. Indices run over elements, then over local nodes, then over components. The last optional axis can be used to represent the field for different modes.

    If None, the method assumes that one of the Maxwell solvers (driven or eigenmode) has been run and its result is used to find the energy.

  • region – String labeling the physical group of a region for which the energy is computed. If None, the energy is computed for the entire device.

Returns:

Time-averaged electric energy, given by

\[\int_{\Omega} \varepsilon \dfrac{\vec E^* \cdot \vec E}{4} d\Omega,\]

where \(\Omega\) is either the region or the entire device.

Raises:

ValueError – If the results of the Maxwell equation solvers are not stored in the device, which occurs if the solvers have not been run.

Note

In version 2.1.3, the definition of the output of this method has changed by a factor of 1/2. This note will be removed in version 2.3.

energy_e_elems(e: ndarray[Shape3D | Shape4D, dtype[complex128 | floating]]) ndarray[Shape1D | Shape2D, dtype[floating]]

Finds the time-averaged electric energy in each element from electric field.

Parameters:

e – Frequency-domain electric field in the device. Indices run over elements, then over local nodes, then over components. An optional last axis can be used for multiple modes.

Returns:

Array representing the time-averaged electric energy, given by

\[\int_{\Omega_e} \varepsilon \dfrac{\vec E^* \cdot \vec E}{4} d\Omega_e.\]

Indices run over elements. If an axis for modes is present, the last axis corresponds to the mode index.

Note

In version 2.1.3, the definition of the output of this method has changed by a factor of 1/2. This note will be removed in version 2.3.

get_N_particle_subspace(particle_number)

Gets the many-body subspace with a certain number of particles.

Parameters:

particle_number (int) – The number of particles in the subspace to get.

Returns:

Subspace object – A many-body subspace object.

get_Vconf()

Getter for the total confinement potential energy.

Returns:

2d Field – The total confinement potential energy in Joules at each local node.

Note

The total confinement potential energy is Vconf = V + Vext.

get_Vmin()

Gets the minimum potential energy.

Returns:

float – The minimum potential energy in Joules.

get_b_field_maxwell() ndarray[complex128]

Obtains the magnetic flux density in the device from the solution of the Maxwell equations.

Returns:

Magnetic flux density at local nodes. For 3D, indices run over elements, then local nodes, then components, then modes. For 2D, indices run over elements, then local nodes, then modes.

get_current_source_voltage(bnd_spec: str) float | complex | Array1D[complex128]

Find the current source voltage using the result of the driven Maxwell equation solver stored in the device.

Parameters:

bnd_spec – Name of the physical group in the mesh corresponding to the current source boundary.

Returns:

Frequency-domain voltage across the current source at the driving frequency. If the driven Maxwell solver was run with split excitations, an array containing the voltage for each excitation is returned.

Note

  1. The boundary needs to have been created using the new_current_source method and the driven Maxwell solver needs to have been executed prior to computing the voltage.

  2. Polarity: The passive sign convention is adopted, where the current flows from the positive terminal to the negative terminal.

Raises:

ValueError – If the results of the Maxwell equation solvers are not stored in the device, which occurs if the solvers have not been run.

get_e_field_maxwell() ndarray[float | complex128]

Obtains the electric field in the device from the solution of the Maxwell equations.

Returns:

Electric field at local nodes. Indices run over elements, then local nodes, then components, then modes.

Raises:

ValueError – If the results of the Maxwell equation solvers are not stored in the device, which occurs if the solvers have not been run.

get_electron_g_factor()

Get the g-tensor for electrons

Returns:

(2D or 3D array) – If the g-factor has been set by the user, a 2D array is returned. This array represents the isotropic g-tensor of the device. If the g-factor has not been set, it is constructed from the material parameters of the materials making up the device. In this case, a 3D array is returned, where the first index runs over the elements of the mesh (over which the device is defined) and the second and third indices run over directions.

Note

The g-tensor can be constructed from the g-factor because we assume that the tensor are isotropic (proportional to the identity matrix).

get_hole_Zeeman_params()

Get the g tensors for the holes.

Returns:

(tuple) – The first entry of the tuple is the kappa g-tensor, and the second is the q g-tensor. If these have not been set by the user using the set_hole_zeeman_params<qtcad.device.device.Device.set_hole_zeeman_params() method, they are constructed from the materials defining the regions of the device and are position-dependent. The output tensors are 3D arrays in this case where the first index runs over the elements of the mesh and the second and third indices run over directions. In the case where the user sets the paramters values, using the set_hole_Zeeman_params method, they are assumed to be constant throughout the device and are returned as 2D arrays.

Note

The g-tensors can be constructed from g-factors because we assume that tensors are isotropic (proportional to the identity matrix).

get_impedance(ports: list[str]) Array2D[complex128]

Compute the impedance (Z) matrix for a given list of ports using the results of a multi-excitation driven Maxwell solver run.

Parameters:

ports – List of names of the physical groups in the mesh corresponding to the ports to include in the Z-matrix.

Returns:

Square impedance matrix of size equal to the number of ports.

Note

  1. The driven Maxwell solver must have been run with split_excitations=True prior to calling this method.

  2. The ports must be a subset of the boundaries created using the new_current_source method that were active during the solver run.

Ref:

Pozar, David M. “Microwave engineering.” Fourth Edition, John Wiley & Sons, Inc (2012).

Raises:
  • ValueError – If the driven Maxwell solver has not been run with split_excitations=True prior to calling this method.

  • ValueError – If any of the requested ports were not found in the device.

  • ValueError – If any of the requested ports were not included as excitations in the multi-excitation solver run.

  • ValueError – If the current of any of the current sources in ports is exactly zero.

  • TypeError – If any of the boundaries in ports does not correspond to a current source created via new_current_source.

get_inductance(bnd_spec: str) float

Get the inductance of an inductive boundary.

Parameters:

bnd_spec (str) – Name of the physical group in the mesh corresponding to the boundary. This boundary must have been created via new_inductor or new_rlc_port.

Returns:

The inductance of the boundary. For 3D, the value is in henries. For 2D, we assume that the inductor extends infinitely in the implied third dimension (\(z\)) and that the inductance is inversely proportional to the width in that dimension. The returned value is the inductance for a unit-width inductor (in henries x meters).

get_inductor_current(bnd_spec: str) ndarray[tuple[Any, ...], dtype[floating | complexfloating]]

Finds the inductor current using the result of Maxwell equation solvers stored in the device.

Parameters:

bnd_spec – name of the physical group in the mesh corresponding to the inductor or RLC port boundary.

Returns:

Frequency-domain current in the inductor. If the Maxwell eigenmode solver was used, indices run over the modes. If the driven Maxwell solver was used, the output is a single-element array.

Note

  1. The boundary needs to have been created using the new_inductor or new_rlc_port (with an inductive component) method and one of the Maxwell solvers (driven or eigenmode) needs to have been executed prior to computing the inductor current.

  2. For RLC ports, the returned current is the current through the inductive branch.

  3. The direction is assumed to be in the positive \(x\), \(y\), or \(z\) direction, aligned with the dir input of the method that was used to create the boundary.

Raises:

ValueError – If the results of the Maxwell equation solvers are not stored in the device, which occurs if the solvers have not been run.

get_k_squared(state=0, directions=2)

Compute expectation value of momentum squared.

Parameters:
  • state (int) – which state we wish to compute the expectation value of. Defaults to 0, i.e. the ground state

  • directions (list or int, optional) – list of directions for which we want the expectation values. 0 <-> ‘x’, i.e. <kx^2>, 1 <-> ‘y’, i.e. <ky^2>, and 2 <-> ‘z’, i.e. <kz^2>. If an integer is used, a single value will be output.

Returns:

list or float – Expectation values of the required momentum operators squared.

Note

The device must contain a non-trivial eigenfunctions attribute in order for this method to be applied. This is typically achieved using the Schrodinger or Schrodinger-Poisson solver.

get_many_body_density(particle_number, eigenstate_index)

Gets the many-body particle density of a certain eigenstate for a given particle number.

Parameters:
  • particle_number (int) – The number of particles in the many-body subspace of interest.

  • eigenstate_index (int) – The index of the many-body eigenstate within the subspace.

Returns:

1D array – The particle density at each global node of the mesh.

get_material_index()
This function assigns a material index to each element of the mesh.

The map between the material and the material index is printed.

Returns:

Field

1D Field running over the elements of the mesh or submesh whose

entries are the material index for the corresponding element. The material index is an integer starting from 1. Each material has its own corresponding index.

Note

The material index is determined by the order in which each material was added to the device via the new_region method.

get_potential_nrg()

Calculates the potential energy from the electric potential and band parameters.

get_region_index()

This function assigns a region index to each element of the mesh.

Returns:

region_idx

1D Field running over the elements of the mesh or submesh whose

entries are the region indices for the corresponding elements. The region index is an integer starting from 1. Each region has its own corresponding index.

Note

The region index is determined by the order in which each region was added to the device via the new_region method.

get_scattering_matrix(ports: list[str], z0: float = 50.0) Array2D[complex128]

Compute the scattering (\(\mathbf S\)) matrix for a given list of ports.

Parameters:
  • ports – List of names of the physical groups in the mesh corresponding to the ports to include in the \(\mathbf S\) matrix.

  • z0 – Characteristic impedance of the ports (in ohms). Default: 50.0.

Returns:

Square scattering matrix of size equal to the number of ports in ports.

Ref:

Pozar, David M. “Microwave engineering.” Fourth Edition, John Wiley & Sons, Inc (2012).

Raises:
  • ValueError – If the driven Maxwell solver has not been run with split_excitations=True prior to calling this method.

  • ValueError – If any of the requested ports were not found in the device.

  • ValueError – If any of the requested ports were not included as excitations in the multi-excitation solver run.

  • ValueError – If the current of any of the current sources in ports is exactly zero.

  • TypeError – If any of the boundaries in ports does not correspond to a current source created via new_current_source.

load(path)

Loads a device from a json file.

new_current_source(bnd_spec: str, current: float | complex, dir: str, length: float, width: float = 1.0)

Add a lumped current source.

Parameters:
  • bnd_spec – Name of the physical group in the mesh corresponding to the boundary. The boundary must be rectangular, with dimensions consistent with length and width arguments.

  • current – Total current flowing through the source.

  • dir – Direction assumed for the current, i.e. “x”, “y”, or “z”, which respectively correspond to the current flowing in the positive \(x\), \(y\), and \(z\) directions.

  • length – Length of the current source (must be consistent with the physical length of the boundary over which the source is defined).

  • width – Width of the current source (must be 1.0 for 2D; for 3D, must be consistent with the physical width of the boundary over which the source is defined).

Note

  1. Warning: The new_current_source method is in beta. Its API may change in future versions.

  2. The method imposes a uniform surface current density everywhere on the boundary, which flows in the direction indicated by dir.

new_dirichlet_bnd(bnd_spec, phi)

Create a Dirichlet boundary, i.e. an essential boundary in which the potential is set directly by the user (no built-in potential).

Parameters:
  • bnd_spec (str | list of str | or ndarray) – Boundary specifier.

  • phi (float) – Electric potential at the boundary.

Note

The boundary specifier is typically the string labeling the physical group for the boundary defined in the mesh file. This can be a string labeling a surface or a volume. In the case of a volume, the boundary condition is applied to all the surfaces surrounding the volume.

It may otherwise be a 1d array of integers labeling each global node in the boundary, or a 2d array of integers labeling each local node in the boundary.

new_frozen_bnd(bnd_spec, phi, material, doping, doping_type, binding_energy, dopant_degen=None)

Create a frozen boundary, i.e. an Ohmic boundary with a semiconductor at equilibrium, for which the electric potential is calculated assuming the chemical potential lies between the dopant level and the band edge, an assumption that only becomes valid at low temperature.

Parameters:
  • bnd_spec (str | np.ndarray | list[str | np.ndarray]) – Boundary specifier.

  • phi (float) – Potential applied at the boundary.

  • material (material object | list[material object]) – The material for the semiconductor at the boundary.

  • doping (int | float | Field | list[int | float | Field]) – The doping concentration of the semiconductor at the boundary.

  • doping_type (str | list[str]) – The type of doping: “n” or “p”.

  • binding_energy (float | list[float]) – The binding energy of the dopants

  • dopant_degen (int or None, optional) – The dopant level degeneracy. If None, uses default value: 2 for donors, 4 for acceptors.

Note

The boundary specifier is typically the string labeling the physical group for the boundary defined in the mesh file. This can be a string labeling a surface or a volume. In the case of a volume, the boundary condition is applied to all the surfaces surrounding the volume.

It may otherwise be a 1d array of integers labeling each global node in the boundary, or a 2d array of integers labeling each local node in the boundary.

The material, doping and doping enegy of the boundary must match the length of the boundary specifier if it is a list. If it is a single value, it is applied to all boundaries specified by the boundary specifier.

new_gate_bnd(bnd_spec, phi, Ew)

Create a gate boundary, i.e. an essential boundary with a primary variable equal to the total potential due to the metal work function and an applied potential.

Parameters:
  • bnd_spec (str | np.ndarray | list[str | np.ndarray]) – Boundary specifier.

  • phi (float) – Potential applied at the boundary.

  • Ew (int | float | Field | list[int | float | Field]) – Metal work function.

Note

The boundary specifier is typically the string labeling the physical group for the boundary defined in the mesh file. This can be a string labeling a surface or a volume. In the case of a volume, the boundary condition is applied to all the surfaces surrounding the volume.

It may otherwise be a 1d array of integers labeling each global node in the boundary, or a 2d array of integers labeling each local node in the boundary.

The metal work function must match the length of the boundary specifier if it is a list. If it is a single value, it is applied to all boundaries specified by the boundary specifier.

new_inductor(bnd_spec: str, inductance: float, dir: str, length: float, width: float | None = 1.0)

Add a lumped element inductor.

Parameters:
  • bnd_spec – name of the physical group in the mesh corresponding to the boundary. In 3D, the boundary must be rectangular, with dimensions consistent with length and width arguments. In 2D, the boundary must be a straight line segment, with length equal to the value of the length argument.

  • inductance – the inductance of the inductor. For 2D, we assume that the inductor extends infinitely in the implied third dimension (\(z\)) and that the inductance is inversely proportional to the width in that dimension. The value of this inductance argument is the value for a unit-width inductor.

  • dir – direction assumed for the current ("x", "y", or "z")

  • length – length of the inductor (must be consistent with the physical length of the boundary over which the inductor is defined).

  • width – width of the inductor (must be 1.0 for 2D; for 3D, must be consistent with the physical width of the boundary over which the inductor is defined).

Warning

This method is in beta. Its API may change in future versions.

Note

  1. This type of boundary is only used in the Maxwell eigensolver and is ignored by other solvers.

  2. The method assumes that the surface current density is uniform everywhere on the boundary and flows in the direction dictated by "dir".

new_insulator(bnd_nodes, set_no_charge=True)

Add an insulator boundary to the list of Schrödinger boundaries.

Parameters:
  • bnd_nodes (1D array | str | list of str) – Indices of the global nodes that belong to the boundary or label(s) of the surfaces making up the boundary.

  • set_no_charge (bool, optional) – If True, make sure that all classical charge vanishes inside the insulator nodes. Default: True.

new_ohmic_bnd(bnd_spec)

Create an Ohmic boundary, i.e. an essential boundary with a primary variable equal to the built-in potential determined by the the doping properties and material properties at the nodes belonging to the boundary.

Parameters:

bnd_spec (str | np.ndarray | list[str | np.ndarray]) – Boundary specifier.

Note

The boundary specifier is typically the string labeling the physical group for the boundary defined in the mesh file. This can be a string labeling a surface or a volume. In the case of a volume, the boundary condition is applied to all the surfaces surrounding the volume.

It may otherwise be a 1d array of integers labeling each global node in the boundary, or a 2d array of integers labeling each local node in the boundary.

new_pec_bnd(bnd_spec: str)

Add a perfect electric conductor boundary for the Maxwell equation.

Parameters:

bnd_spec – name of the physical group in the mesh corresponding to the boundary. The boundary bnd_spec can belong to the exterior boundary of the device or it can be embedded inside the device. An error is raised if part of the elements of the boundary bnd_spec are inside the domain and another part of the elements are on the exterior boundary.

new_periodic_bnd(main_bnd_spec, follow_bnd_spec)

Create a periodic boundary condition. This boundary condition is used to treat two parallel boundaries (denoted main and follower) as if they were identical and the system were tiled infinitely across space (in the direction perpendicular to the boundaries).

Parameters:
  • main_bnd_spec (str or ndarray) – Boundary specifier for the main boundary.

  • follow_bnd_spec (str or ndarray) – Boundary specifier for the follower boundary which is treated as if it were identical to the main boundary.

Note

The boundary specifier is typically the string labeling the physical group for the defined boundaries in the mesh file.

It may otherwise be a 1d array of integers labeling each global node in the boundary, or a 2d array of integers labeling each local node in the boundary.

The periodic boundaries must be parallel and related to one another by a translation along an axis perpendicular to their two surfaces.

When the periodic and essential boundaries overlap, the essential boundary condition is not applied at the overlapping nodes.

The number of nodes in the main and follower boundaries must be the same. This can be achivied by using a symmetric mesh, extruded mesh, or using the Periodic Surface option in Gmsh.

new_quantum_lead_bnd(bnd_spec, essential=False)

Adds a boundary interfacing with a quantum lead.

Parameters:
  • bnd_spec (str or ndarray) – Boundary specifier.

  • essential (bool) – whether the boundary is essential (natural). essential=False if floating source (Neumann) boundary applies. In this case, the electrical boundary value is determined by resolving the electronic structure in the lead and its quantum statistics.

new_region(tag, material, pdoping: float = 0, ndoping: float = 0, ionization_model=None, Ea=None, Ed=None, gD=None, gA=None)

Create a region and add it to the device.

Parameters:
  • tag (str or int) – The physical group tag (name or integer) to associate with the physical volume in the mesh file.

  • material (material object) – The material of which the region consists. This attribute is optional.

  • pdoping (float, optional) – The density of acceptors in m^-3. Default: 0.

  • ndoping (float, optional) – The density of donors in m^-3. Default: 0.

  • ionization_model (string, optional) – The ionization model used in this Region. Default: None, which means that the default ionization model stored in the device will be used, which itself is “complete” by default.

  • Ed (float, optional) – The donor binding energy. If None, does not modify the value currently stored in the device.

  • Ea (float, optional) – The acceptor binding energy. If None, does not modify the value currently stored in the device.

  • gD (int, optional) – The donor level degeneracy. If None, uses the default value for the current material.

  • gA (int, optional) – The acceptor level degeneracy. If None, uses the default value for the current material.

new_rlc_port(bnd_spec: str, admittance: dict[str, float], dir: str, length: float, width: float = 1.0)

Add a parallel RLC port.

Parameters:
  • bnd_spec – name of the physical group in the mesh corresponding to the boundary. The boundary must be rectangular, with dimensions consistent with length and width arguments.

  • admittance – dictionary with keys "1", "i_omega" and "1/i_omega", indicating the factors of the three parts of the admittance expressions below.

    3D case:

    \[Y = Y_1 + i \omega Y_{i\omega} + \frac{1}{i\omega} Y_{1/i\omega}\]

    2D case (admittance per unit width in the implied third dimension):

    \[Y' = Y'_1 + i \omega Y'_{i\omega} + \frac{1}{i\omega} Y'_{1/i\omega}\]

    The values in the dictionary are as follows:

    • "1": \(Y_1\) in siemens (3D) or \(Y'_1\) in siemens/meter (2D).

    • "i_omega": \(Y_{i\omega}\) in farads (3D) or \(Y'_{i\omega}\) in farads/meter (2D).

    • "1/i_omega": \(Y_{i\omega}\) in 1/henry (3D) or \(Y'_{i\omega}\) in 1/henry/meter (2D).

  • dir – Direction assumed for the current ("x", "y" or "z").

  • length – Length of the inductor (must be consistent with the physical length of the boundary over which the inductor is defined).

  • width – Width of the inductor (must be equal to one for 2D; for 3D, must be consistent with the physical width of the boundary over which the inductor is defined).

Warning

This method is in beta. Its API may change in future versions.

Note

  1. This type of boundary is only used in the Maxwell eigensolver and is ignored by the other solvers.

  2. The method assumes that the surface current density is uniform everywhere on the boundary and flows in the direction dictated by "dir".

new_schottky_bnd(bnd_spec, phi, barrier)

Create a Schottky boundary, i.e. an essential boundary with a primary variable equal to the total potential due to the Schottky barrier height and an applied potential.

Parameters:
  • bnd_spec (str | np.ndarray | list[str | np.ndarray]) – Boundary specifier.

  • phi (float) – Potential applied at the boundary.

  • barrier (int | float | Field | list[int | float | Field]) – Schottky barrier height.

Note

The boundary specifier is typically the string labeling the physical group for the boundary defined in the mesh file. This can be a string labeling a surface or a volume. In the case of a volume, the boundary condition is applied to all the surfaces surrounding the volume.

It may otherwise be a 1d array of integers labeling each global node in the boundary, or a 2d array of integers labeling each local node in the boundary.

The Schottky barrier height must match the length of the boundary specifier if it is a list. If it is a single value, it is applied to all boundaries specified by the boundary specifier.

new_surf_current_density(bnd_spec: str, density: ndarray[tuple[Any, ...], dtype[floating | complexfloating]])

Sets a constant surface current density at a boundary or interface.

Parameters:
  • bnd_spec – name of the physical group in the mesh corresponding to the boundary.

  • density – 1D array representing the surface current density at the frequency of interest. Its direction must be tangential to the surface. Indices run over the Cartesian components of the current density. The value is assumed constant at every point on the boundary.

print_N_body_energies(N)

Prints the N-body energies.

Parameters:

N (int) – Particle number of the subspace.

print_energies(decimals=8)

Print energy levels in eV.

Parameters:

decimals (int, optional) – Number of decimals to print.

Note

For holes the energies printed are those consistent with the convention defined in QTCAD convention for holes, i.e. the convention takes holes to be particles with positive mass and charge.

print_ith_evec(N, i)

Prints the energy and eigenvector of a given N-particles state.

Parameters:
  • N (int) – Particle number of the subspace.

  • i (int) – eigenvalue index

reset_dot_region()

Resets this device in a state with no dot region defined.

save(path='device.hdf5', attrs=None)

Saves the device into a json or hdf5 file.

Parameters:
  • path (string, optional) – The path to the file in which to save the device. Default: device.hdf5 in current dir.

  • attrs (list of str or None, optional) – Attributes to save in the json or hdf5 file. If None, save all of them.

  • bnd_list_names (list of str, optional) – Names of the device attributes that are actually lists of boundaries.

save_energies(path)

Save energies and population factors resulting from the self-consistent Schrodinger-Poisson solution in a text file.

set_Bfield(B: Callable | ndarray[tuple[Any, ...], dtype[float64]], r0: Tuple[float, float, float] = (0.0, 0.0, 0.0), gauge: str = 'symmetric') None

Set the magnetic field.

Parameters:
  • B (Callable or numpy array) – Magnetic field defined over the device. If callable, the function must return a 3-component magnetic field vector as a function of position. If a numpy array is used, accepted shapes are (3,) or (1, 3) for a constant magnetic field throughout the device, and (self.mesh.node_number, 3) or (3, self.mesh.node_number) for a field defined at every global mesh node.

  • r0 (tuple, optional) – Defaults to (0, 0, 0). Three-tuple defining the origin of the coordinate system. Used when computing the vector potential.

  • gauge (string, optional) – Defaults to “symmetric”. The gauge of the vector potential. Currently available: “symmetric” and “landau”.

Note

The arguments r0 and gauge are only used when orbital magnetic

effects are modelled.

Orbital magnetic effects can only be modelled if the magnetic

field is constant, i.e. B must have shape (3,) or (1, 3).

Zeeman and/or orbital magnetic field effects can be turned off by

setting the zeeman and/or orb_B_effects attributes to False. This can be done using the methods set_Zeeman and set_orb_B_effects, respectively.

set_V(V, region=None)

Setter for the intrinsic confinement potential energy. Sets the this potential energy to arbitrary user-defined values without accounting for conduction and valence band edges.

Parameters:
  • V (1D array, 2D array, function or float) – Value of the confinement potential at each node.

  • region (string or None) – If string, sets the value of the potential to V for every element in the region. In this case, V must be a float.

Note

The total confinement potential energy is Vconf = V + Vext.

set_V_from_phi()

Calculates the potential energy from the electric potential and band parameters.

set_Vext(Vext, region=None)

Setter for the external confinement potential energy

Parameters:
  • Vext (1D array, 2D array, function or float) – Value of the external confinement potential at each node.

  • region (string or None) – If string, sets the value of the potential to Vext for every element in the region. In this case, Vext must be a float.

Note

The total confinement potential energy is Vconf = V + Vext.

set_Zeeman(value: bool) None

Set the zeeman attribute.

Parameters:

value (bool) – Whether or not to include Zeeman effects when solving the Schrodinger equation.

set_acceptor_binding_nrg(Ea, region=None)

Sets the acceptor binding energy Ea.

Parameters:
  • Ea (1D array, 2D array, function or float) – The values of the binding energy.

  • region (string or None, optional) – If string, sets the value of the binding energy to Ea for every element in this region. In this case, Ea must be a float.

set_acceptor_degen(gA, region=None)

Sets the acceptor level degeneracy gA.

Parameters:
  • gA (1D array, 2D array, function or int) – The values of the binding energy.

  • region (string or None, optional) – If string, sets the value of the acceptor degeneracy to gA for every element in this region. In this case, gA must be a float.

set_acceptor_density(NA, region=None)

Sets the acceptor density NA.

Parameters:
  • NA (1D array, 2D array, function or float) – The values of the acceptor density.

  • region (string or None, optional) – If string, sets the value of the acceptor density to NA for every element in this region. In this case, NA must be a float.

set_applied_potential(bnd_label, phi_a)

Set the applied potential at some boundary.

Parameters:
  • bnd_label (str) – The boundary label

  • phi_a (float) – The potential to apply

Note

The boundary must support applied potentials. This is the case for, e.g., gate and Schottky boundaries.

set_charge_density(rho, region=None)

Sets the charge density. Used only by the linear Poisson solver.

Parameters:
  • rho (float, ndarray, or function) – Charge density specification. Supported inputs are:

    • float:

      Assigns a constant charge density throughout the device.

    • ndarray:

      Assigns charge density values using either global-node or local-node representations. A 1D array corresponds to the global-node representation. Its length must equal the number of global mesh nodes, with each entry defining the value at the corresponding node. A 2D array corresponds to the local-node representation. Its shape must be (n_elements, n_local_nodes), where n_elements and n_local_nodes are, respectively, the number of element in the mesh and the number of local nodes per element. In this case, each row corresponds to a mesh element and each column corresponds to a local node within an element, following the element connectivity ordering.

    • function:

      Assigns charge density by evaluating a function f at each mesh node. The function must accept Cartesian coordinate(s) (x, y, and z) corresponding to the device dimensionality:

      • 1D: f(x)

      • 2D: f(x, y)

      • 3D: f(x, y, z)

  • region (string or None, optional) – If string, sets the value of the charge density to rho for every element in this region. In this case, rho must be a float.

Note

In the non-linear Poisson solver, the device attribute rho will be overwritten at every self-consistent iteration by the equilibrium semiconductor charges (electron and hole densities, and ionized donor and acceptor densities). To add a fixed background volume charge that will be accounted for by the non-linear Poisson solver, please see set_vol_charge_density.

set_cond_band_edge(EC)

Set the electric potential to correspond to a given conduction band edge.

Parameters:

EC (1d array or 2d array) – The conduction band edge at each global or local node.

set_coulomb_mat(coulomb_mat)

Sets the Coulomb interaction matrix

Parameters:

coulomb_mat (2d or 4d array) – The Coulomb interaction matrix. If a 2D array is used, it is assumed that the overlaps between basis states are neglected. Otherwise, the full 4D interaction matrix is used.

set_donor_binding_nrg(Ed, region=None)

Sets the donor binding energy Ed.

Parameters:
  • Ed (1D array, 2D array, function or float) – The values of the binding energy.

  • region (string or None, optional) – If string, sets the value of the binding energy to Ed for every element in this region. In this case, Ed must be a float.

set_donor_degen(gD, region=None)

Sets the donor level degeneracy gD.

Parameters:
  • gD (1D array, 2D array, function or int) – The values of the binding energy.

  • region (string or None, optional) – If string, sets the value of the donor degeneracy to gD for every element in this region. In this case, gD must be a float.

set_donor_density(ND, region=None)

Sets the donor density ND.

Parameters:
  • ND (1D array, 2D array, function or float) – The values of the donor density.

  • region (string or None, optional) – If string, sets the value of the donor density to ND for every element in this region. In this case, ND must be a float.

set_dot_region(dot_region)

Define global nodes corresponding to the quantum dot (quantum confined) region.

Parameters:

submesh (string, SubMesh or list) – Submesh or list of submeshes corresponding to the dot region, or string or list of strings labeling region of the device (Gmsh physical groups), or list of lists/tuples defining corners of a box for each dot

Note

The dot region is internally defined as a list of region labels or SubMesh objects. If this method is called multiple times on the same Device object, inputs are concatenated together in the list. For example, calling this method first with dot_region="region_1", and then with dot_region="region_2" results in a dot region which is the union of global nodes belonging to "region_1" and "region_2".

Classical charge density for confined carriers is set to zero inside the dot region when using the non-linear Poisson solver. Both classical and confined charge for electrons and holes (i.e., all charge except those due to ionized dopant densities) are set to zero inside the dot region when using the quantum-well solver.

set_electron_kp_model(model: ElectronKPModel | None) None

Set the electron k·p model used by the device.

Parameters:

model – Electron k·p model object to attach to the device, or None to clear the current model.

set_electron_kp_param(name: str, value: ndarray[tuple[Any, ...], dtype[number]] | number | complex | float | int | Callable) None

Set a named electron k·p parameter on the device.

Parameters:
  • name – Name of the electron k·p parameter.

  • value – Parameter value to store on the device. This value can be passed as a numeric value (float, complex, int, array) or a callable of position (e.g. \(x\), \(y\), and \(z\) in 3D) that returns a numeric value.

set_fermi_lvl(EF, region=None)

Sets the Fermi energy level.

Parameters:
  • EF (1D array, 2D array, function or float) – The values of the Fermi energy.

  • region (string or None, optional) – If string, sets the value of the Fermi energy to EF for every element in this region. In this case, EF must be a float.

set_g_star(g_star)

Setter for effective g-factor for electrons

Parameters:

g_star (float) – g-factor associated with the coupling between the magnetic field and the angular momentum operators

Note

If this setter is used, the same isotropic g-tensor is assumed to be valid for all nodes of the device.

set_hole_zeeman_params(kappa, q)

Setter for hole Zeeman parameters

Parameters:
  • kappa (float) – g-factor associated with the coupling between the magnetic field and the angular momentum operators

  • q (float) – g-factor associated with the coupling between the magnetic field and the angular momentum operators to the third power

  • Note – If this setter is used, the same isotropic g tensors are assumed to be valid for all nodes of the device.

set_insulator_boundaries()

Set an insulator boundary condition on all the external boundaries of the mesh.

set_inv_effective_mass_tensor(Me_inv: ndarray)

Setter for the inverse effective mass tensor. Used to set the the inverse effective mass tensor to a given value throughout the device.

Parameters:

Me_inv (numpy array) – \(3 imes 3\) numpy array that defines the inverse effective mass tensor throughout the device.

set_ionization_model(model)

Sets the default ionization model of the device.

Parameters:

model (string) – The model to be used.

Note

Available models are “complete” and “incomplete”.

set_kp_model(model)

Sets the k.p model for the holes in the device.

Parameters:

model (string) – The name of the k.p model to use. The string should be the name of a function in the kp module. module of the materials package.

Note

The default model is the four-band ‘luttinger_kohn_foreman’ model. This method must be called before any region has been defined in this Device. This is because the \(\mathbf D\)-matrix defining the kinetic energy term in the \(\mathbf k \cdot \mathbf p\) effective Schrödinger equation is calculated for each region based on the material properties of the region and the k.p model defined in this method.

set_orb_B_effects(value: bool) None

Set the orb_B_effects attribute.

Parameters:

value (bool) – Whether or not to include orbital magnetic effects when solving the Schrodinger equation.

set_permittivity(eps, region=None)

Sets the permittivity.

Parameters:
  • eps (1D array, 2D array, function or float) – Value of the permittivity at each node.

  • region (string or None) – If string, sets the value of the permittivity to eps for every element in the region. In this case, eps must be a float.

set_potential(phi)

Set the electric potential.

Parameters:

phi (1d array) – Value of the potential at each global node.

set_soc(soc, region=None)

Add a spin-orbit coupling (soc) term to the model.

Parameters:
  • soc (list of 2D numpy arrays or function) – Each entry of the list contains the matrix proportional to kx, ky, and kz respectively which encodes a particular form of soc. If there is no coupling for a particular k direction, the entry in the tuple can be set to None. If a function, it must take as arguments x, y, and z and output a 3D numpy array where the first index runs over the coupling to kx, ky, and kz, and the second and third indices run over the bands of the model.

  • region (string or None) – If string, sets the value of the attribute to soc for every element in the region

Note

The spin-orbit coupling terms are symmetrized such that \(H_{\mathrm{SOC}} = \sum_{i}\left[\alpha_i k_i / 2 + k_i \alpha_i/2\right]\), where the \(\alpha_i\) are the specified matrices and i runs over \(x\), \(y\), and \(z\). This symmetrization may not be physically justified and have important consequences when the spin-orbit couplings are taken to be spatially varying (the \(\alpha_i\) depend on position), since the \(\alpha_i\) and \(k_i\) do not necessarily commute. This may lead to inaccurate results if \(\alpha_i\) varies significantly over the lengthscale of the envelope functions.

set_strain(strain, region=None)

Setter for strain throughout the device

Parameters:
  • strain (numpy array or func which outputs an array) – 3 x 3 numpy array that defines the uniform strain throughout the device or a function of 3 variables (x, y, z) that outputs a 3 x 3 array defining the strain at every global node of the mesh.

  • region (string or None) – If string, sets the value of the attribute to val for every element in the region

set_surf_charge_density(surf_spec, density)

Sets the surface charge density at a boundary or interface.

Parameters:
  • surf_spec (str or ndarray) – Surface specifier.

  • sigma (float) – Surface charge density.

Note

The surface specifier is typically the string labeling the physical group for the surface defined in the mesh file.

It may otherwise be a 1d array of integers labeling each global node in the surface, or a 2d array of integers labeling each local node in the surface.

set_temperature(T)

Sets the device temperature.

Parameters:

T (float) – The device temperature, assumed uniform.

set_valley_splitting(valley_splitting: float) None

Set the valley_splitting attribute.

The valley splitting is applied to conduction-band electrons. When it is set, each original single-particle energy level E is replaced by two valley-resolved branches at E - valley_splitting / 2 and E + valley_splitting / 2.

In the case without an additional spin/band axis, the resulting eigenfunctions attribute has shape (N_nodes, N_levels, 2). For each split pair, the lower-energy branch has nonzero entries only in valley index 0 and vanishing entries in valley index 1, while the higher-energy branch has the opposite structure: valley index 0 vanishes and valley index 1 is nonzero.

In the case of spinful electrons, the resulting eigenfunctions attribute has shape (N_nodes, N_levels, 4). The lower-energy branch then has nonzero entries only in the first two band indices 0 and 1 (valley 1, spin up/down), while the higher-energy branch has nonzero entries only in indices 2 and 3 (valley 2, spin up/down).

After the split branches are created, the single-particle states are stored in ascending energy order.

Note

The Schrödinger solver does not support adding explicit valley splitting when using an electron_kp_model. If this device has an electron_kp_model, the solver raises NotImplementedError; encode valley splitting directly into the electron k·p model instead.

Parameters:

valley_splitting (float) – Non-negative valley splitting energy.

set_vlnce_band_edge(EV)

Set the electric potential to correspond to a given valence band edge.

Parameters:

EV (1d array or 2d array) – The valence band edge at each global or local node.

set_vol_charge_density(rho_0, region=None)

Sets the background volume charge density.

Parameters:
  • rho_0 (float, ndarray, or function) – Charge density specification. Supported inputs are:

    • float:

      Assigns a constant charge density throughout the device.

    • ndarray:

      Assigns charge density values using either global-node or local-node representations. A 1D array corresponds to the global-node representation. Its length must equal the number of global mesh nodes, with each entry defining the value at the corresponding node. A 2D array corresponds to the local-node representation. Its shape must be (n_elements, n_local_nodes), where n_elements and n_local_nodes are, respectively, the number of element in the mesh and the number of local nodes per element. In this case, each row corresponds to a mesh element and each column corresponds to a local node within an element, following the element connectivity ordering.

    • function:

      Assigns charge density by evaluating a function f at each mesh node. The function must accept Cartesian coordinate(s) (x, y, and z) corresponding to the device dimensionality:

      • 1D: f(x)

      • 2D: f(x, y)

      • 3D: f(x, y, z)

  • region (string or None, optional) – If string, sets the value of the background volume charge density to rho_0 for every element in this region. In this case, rho_0 must be a float.

Note

The background volume charge density attribute rho_0 is only used by the non-linear Poisson solver. To set the charge density in a way that will be accounted for by the linear Poisson solver, use set_charge_density instead, which directly sets the total charge density rho used by the linear Poisson solver.

update_mesh(mesh)

Update the mesh over which the device is defined.

Parameters:

mesh (Mesh object) – The new mesh over which the device must now be defined.

vlnce_band_edge()

Output valence band edge at each mesh point.

Returns:

2d Field – The conduction band edge in Joules at each local node.

warning_unassigned_region()

Issues a warning if there is any part of the device that is not assigned a region

class SubDevice(parent, submesh)

Bases: _VisConvenienceMixin, SubDevice

A subdevice is a device built from a parent device from a submesh which is a subset of the mesh of the parent device.

__init__(parent, submesh)

Constructor of the SubDevice class.

Parameters:
  • parent (Device object) – The Device object from which the subdevice is built.

  • submesh (SubMesh object) – The SubMesh object over which the subdevice is defined.

delete()

Removes the subdevice from memory.

Note

This also removes any reference to the subdevice from its parent device.