pynitride.physics.carriers module

class pynitride.physics.carriers.CarrierModel(mesh)

Bases: object

Superclass for all carrier models.

A carrier model implements a solve() function and a repopulate() function, which together define how to get from previously-solved bands to the induced carrier densities.

repopulate()

Populates the mesh with carriers.

This method should be quick because solve() has already done the heavy lifting. So this can be called inside tighter loops where the Fermi level changes but bands do not.

Precondition: self.solve() has already been called to set up any necessary resources (eg wavefunctions) and the mesh includes the Fermi level “EF” (e.g. provided by Equilibrium).

Post-condition: the mesh will have the electron and hole densities “n” and “p”, as well as their approximate functional derivatives “nderiv” and “pderiv” with respect to the bands (ie \(n' = \delta n / \delta [-q \phi],\ p' = \delta p / \delta [-q \phi]\))

solve()

Performs any prep work needed (e.g. solving for wavefunctions) before the mesh can be populated.

This method generally does the expensive eigenvalue calculations, whereas repopulate() simply takes these results and fills in the levels.

Precondition: the mesh already includes the bands “Ec” and “Ev” (e.g. provided by Poisson).

Post-condition: One can now call repopulate()

solve_and_repopulate()

Calls solve() and repopulate()

class pynitride.physics.carriers.MultibandKP(mesh, rmesh=None, num_eigenvalues=20, carriers=['hole'])

Bases: CarrierModel

Solves the multiband k.p problem for the valence bands.

Can use either a 1D line of k-points or a rectangular ‘xy’ grid of k-points or a polar grid of k-points depending on kmeshmethod. Regardless, assumes in-plane inversion symmetry (ie for 1D, only solves at positive kx, and for 2D only solves one quadrant of k-plane for efficiency.

Parameters:
  • mesh – the pynitride.mesh.Mesh on which to solve

  • rmesh – the reciprocal mesh on which to solve (if you only want to use MultibandKP.solve_one_k(), this is not needed)

  • num_eigenvalues – (int) the number of eigenvalues to solve for at each k-point

  • carriers[‘hole’] or [‘electron’], can’t do both yet.

interp_energy(absk, theta, eig, bounds_check=True, grid=False)

Returns spline-interpolated results for the energy

Parameters:
  • absk – radial coordinate

  • theta – angular coordinate

  • eig – which eigenvalue

  • bounds_check – whether to throw out-of-bounds errors

  • grid – as in scipy.interpolate.BivariateSpline

Returns:

return shape determined by grid as in scipy.interpolate.BivariateSpline

interp_group_velocity(absk, theta, eig, bounds_check=True, grid=False)

Returns spline-interpolated results for the 2D-vector group velocity

Parameters:
  • absk – radial coordinate

  • theta – angular coordinate

  • eig – which eigenvalue

  • bounds_check – whether to throw out-of-bounds errors

  • grid – as in scipy.interpolate.BivariateSpline

Returns:

tuple of (vx, vy), return shape of each determined by grid as in scipy.interpolate.BivariateSpline

interp_radial_eff_mass(absk, theta, eig, bounds_check=True)

Returns spline-interpolated results for the effective mass in the radial direction

ie if evaluated at theta=0, then this is inversely proportional to the second x-derivative of energy. A minus sign is applied to hole effective masses to make them generically positive.

Parameters:
  • absk – radial coordinate

  • theta – angular coordinate

  • eig – which eigenvalue

  • bounds_check – whether to throw out-of-bounds errors

  • grid – as in scipy.interpolate.BivariateSpline

Returns:

return shape determined by grid as in scipy.interpolate.BivariateSpline

interp_radial_group_velocity(absk, theta, eig, bounds_check=True, grid=False)

Returns spline-interpolated results for the group velocity in the radial direction

Parameters:
  • absk – radial coordinate

  • theta – angular coordinate

  • eig – which eigenvalue

  • bounds_check – whether to throw out-of-bounds errors

  • grid – as in scipy.interpolate.BivariateSpline

Returns:

return shape determined by grid as in scipy.interpolate.BivariateSpline

property kpen

The energies, shape (len(kt), num_eigs, mesh.Nn).

property kppsi

The spinor wavefunctions, shape (len(kt), num_eigs, matsys.kp_dim, mesh.Nn).

property mesh
property normsqs

The norm-squareds of the wavefunction, shape (len(kt), num_eigs, mesh.Nn).

repopulate()

Populates the carrier densities onto the mesh, call after MultibandKP.solve()

property rmesh
solve()

Solves the MBKP eigenvalue problem, call before MultibandKP.repopulate()

solve_one_k(kx, ky, ik=None)

Solves the k.p problem for just one wavevector.

Parameters:
  • kx – the in-plane wavevector at which to compute the k.p matrices to solve

  • ky – the in-plane wavevector at which to compute the k.p matrices to solve

  • ik – if specified, this index into the RMesh will be used to find the wavevector instead of the kx,ky

  • used. (arguments. This also allows the pre-calculated k.p matrices to be) –

Returns:

a tuple of eigenvalues (shape num_eigs), eigenvectors (shape num_eigs, matsys.kp_dim, mesh.Nn), and normsqs (shape num_eigs, mesh.Nn)

solve_point_as_bulk(zn=None, kz=0)

Solves the transverse dispersion at a given point as if the material properties there were in bulk.

Parameters:
  • zn – for an actual mesh, zn specifies a z-coord to solve at. Or if a Material.bulk() is used instead to create the MultibandKP, then zn=None is fine.

  • kz – z-wavevector to solve at

class pynitride.physics.carriers.Schrodinger(mesh, carriers=['electron', 'hole'], num_eigenvalues=8, blend=True, transverse='parabolic', boundary=['Dirichlet', 'Dirichlet'])

Bases: CarrierModel

Implements a Schrodinger envelope function carrier model.

Carriers at each point are populated according to band alignment as if that point was the bulk. See solve() for details and see Carrier Models for the physics.

Parameters:
  • mesh (mesh.Mesh) – the Mesh to populate

  • carriers (list of strings) – which carriers to populate, eg ["electron"], ["hole"], or ["electron","hole"]

  • num_eigenvalues (int) – how many eigenvalues to solve for and occupy quantum mechanically. [Default = 8]

  • blend (bool) – whether to add in semiclassically-occupied carriers at energies beyond the solved for levels. [Default = True]

  • transverse (str) – “parabolic” [Default] or “full k-space”, see physics section for details

Superclass for all carrier models.

A carrier model implements a solve() function and a repopulate() function, which together define how to get from previously-solved bands to the induced carrier densities.

repopulate()

Populates the carrier densities onto the mesh, call after Schrodinger.solve()

solve()

Solves the Schrodinger eigenvalue problem, call before Schrodinger.repopulate()

class pynitride.physics.carriers.Semiclassical(mesh, carriers=['electron', 'hole'])

Bases: CarrierModel

Implements a semiclassical carrier model.

Carriers at each point are populated locally according to band alignment as if that point was the bulk. See solve() for details and see Carrier Models for the physics.

Parameters:
  • mesh (Mesh) – the Mesh to populate

  • carriers (list of strings) – which carriers to populate, eg ["electron"], ["hole"], or ["electron","hole"]

Superclass for all carrier models.

A carrier model implements a solve() function and a repopulate() function, which together define how to get from previously-solved bands to the induced carrier densities.

repopulate(Ec_eff=None, Ev_eff=None, addon=False)

Populate carriers semi-classically into the mesh. See CarrierModel.solve() for conditions, and see Carrier Models for the physics.

Accepts effective conduction and valence bands as optional arguments to use in place of the mesh Ec and Ev. For use as a stand-alone model, these should not be supplied, but they are convenient when this model is called by other models which may populate some levels quantum mechanically and then use this function to fill in the rest of the band semiclassically. In this case, the addon option, which adds the computed density to whatever is on the mesh, rather than replacing it, may also come in handy.

Parameters:
  • Ec_eff (Node mesh.Function) – Effective conduction band level, optional.

  • Ev_eff (Node mesh.Function) – Effective valence band level, optional.

  • addon (bool) – Whether to add (True) the computed density to current mesh values or simply replace the

  • values (current) –

solve()

Does nothing.

For Semiclassical, since there are no expensive eigenvalue calculations, all the work is done in repopulate().