qtcad.atoms.schrodinger module

Tight-binding Hamiltonian calculator and sparse eigensolver.

class Solver(atoms: Atoms, solver_params: SolverParams = None)

Bases: Solver

Atomistic tight-binding Schrödinger solver.

Attributes:
  • atoms (Atoms) – Atomic structure.

  • tb_orbs (str) – Atomic orbital basis set used in the tight-binding model, which may either be “sp3” for an \(sp^3\) basis, “sp3s*” for an \(sp^3s^{\star}\) basis, or “sp3d5s*” for an \(sp^3d^5s^{\star}\) basis.

  • tb_spin (bool) – Whether a spin component is included in the tight-binding basis. If False, it is assumed the basis is composed of the atomic orbitals only. If True, it is assumed the basis is twice as large and is composed of the tensor products of the atomic orbitals with the spin up and spin down states. Set to False if and only if both atoms.soc and atoms.zeeman are False.

  • solver_params (SolverParams) – Parameters of the atomistic tight-binding Schrödinger solver.

__init__(atoms: Atoms, solver_params: SolverParams = None) None
Parameters:
  • atoms (Atoms) – Atomic structure over which to solve the atomistic tight-binding Schrödinger equation.

  • solver_params (SolverParams, optional) – Parameters to pass to the atomistic tight-binding Schrödinger solver. If None, parameters are set to reasonable defaults. Default: None.

get_hamiltonian(k: tuple | ndarray = None) bsr_matrix

Construct the full tight-binding Hamiltonian.

Parameters:

k (tuple or Numpy.ndarray, optional) – Vector of the Cartesian coordinates of the crystal wavevector; ignored if the atomic structure does not have periodic boundary conditions. If None, set to (0., 0., 0.), corresponding to the \(\Gamma\) point in the Brillouin zone of the supercell. Default: None.

Returns:

Scipy.sparse.bsr_matrix\(\left(N N_B\right)\times\left(N N_B\right)\) matrix describing the tight-binding Hamiltonian of the atomic structure, where \(N\) is the number of atoms in the structure, where \(N_B = N_O N_S\) is the number of basis states per atom, where \(N_O\) is the number of atomic orbitals per atom (\(N_O = 4\) if tb_orbs is “sp3”, in which case the orbitals are \(\{s\), \(x\), \(y\), \(z\}\), \(N_O=5\) if tb_orbs is “sp3s*”, in which case the orbitals are \(\{s\), \(x\), \(y\), \(z\), \(s^{\star}\}\), and \(N_O=10\) if tb_orbs is “sp3d5s*”, in which case the orbitals are \(\{s\), \(x\), \(y\), \(z\), \(yz\), \(xz\), \(xy\), \(x^2-y^2\), \(3z^2-r^2\), \(s^{\star}\}\)), and where \(N_S\) is the number of spin states per atom (\(N_S = 1\) if tb_spin is False and \(N_S = 2\) if tb_spin is True). The matrix is partitioned into \(N_B\times N_B\) blocks in the \(\{s\), \(x\), \(y\), \(\dots \}\) basis if \(N_S = 1\) or in the \(\{s+\), \(s-\), \(x+\), \(x-\), \(y+\), \(y-\), \(\dots \}\) basis if \(N_S = 2\).

get_hamiltonian_phi() bsr_matrix

Construct contribution to tight-binding Hamiltonian due to the external electric potential.

This matrix is diagonal; its elements are computed through \(-e \varphi\), where \(e\) is the elementary charge and \(\varphi\) is the external electric potential, which is evaluated or interpolated on the atomic positions.

Returns:

Scipy.sparse.bsr_matrix\(\left(N N_B\right)\times\left(N N_B\right)\) matrix describing the contribution of the external electric potential to the tight-binding Hamiltonian of the atomic structure, where \(N\) is the number of atoms in the structure, where \(N_B = N_O N_S\) is the number of basis states per atom, where \(N_O\) is the number of atomic orbitals per atom (\(N_O = 4\) if tb_orbs is “sp3”, in which case the orbitals are \(\{s\), \(x\), \(y\), \(z\}\), \(N_O=5\) if tb_orbs is “sp3s*”, in which case the orbitals are \(\{s\), \(x\), \(y\), \(z\), \(s^{\star}\}\), and \(N_O=10\) if tb_orbs is “sp3d5s*”, in which case the orbitals are \(\{s\), \(x\), \(y\), \(z\), \(yz\), \(xz\), \(xy\), \(x^2-y^2\), \(3z^2-r^2\), \(s^{\star}\}\)), and where \(N_S\) is the number of spin states per atom (\(N_S = 1\) if tb_spin is False and \(N_S = 2\) if tb_spin is True). The matrix is partitioned into \(N_B\times N_B\) blocks in the \(\{s\), \(x\), \(y\), \(\dots \}\) basis if \(N_S = 1\) or in the \(\{s+\), \(s-\), \(x+\), \(x-\), \(y+\), \(y-\), \(\dots \}\) basis if \(N_S = 2\).

Scipy.sparse.bsr_matrix: NMS-by-NMS matrix describing contribution of the external electric potential to the tight-binding Hamiltonian of the atomic structure, where N is the number of atoms in the structure, where M is the number of atomic orbitals per atom (M=4 if tb_orbs is “sp3”, in which case the orbitals are {s, x, y, z}, M=5 if tb_orbs is “sp3s*”, in which case the orbitals are {s, x, y, z, s*}, and M=10 if tb_orbs is “sp3d5s*”, in which case the orbitals are {s, x, y, z, yz, xz, xy, x^2-y^2, 3z^2-r^2, s*}), and where S is the number of spin states per atom (S=1 if tb_spin is False and S=2 if tb_spin is True). The matrix is partitioned into MS-by-MS blocks in the {s, x, y, …} basis if S=1 or in the {s+, s-, x+, x-, y+, y-, …} basis if S=2.

get_hamiltonian_soc() bsr_matrix

Construct contribution to tight-binding Hamiltonian due to spin-orbit coupling.

Returns:

Scipy.sparse.bsr_matrix\(\left(N N_B\right)\times\left(N N_B\right)\) matrix describing the contribution of spin-orbit coupling to the tight-binding Hamiltonian of the atomic structure, where \(N\) is the number of atoms in the structure and where \(N_B\) is the number of basis states per atom (\(N_B = 8\) if tb_orbs is “sp3”, in which case the basis states are \(\{s+\), \(s-\), \(x+\), \(x-\), \(y+\), \(y-\), \(z+\), \(z-\}\), \(N_B = 10\) if tb_orbs is “sp3s*”, in which case the basis states are \(\{s+\), \(s-\), \(x+\), \(x-\), \(y+\), \(y-\), \(z+\), \(z-\), \(s^{\star}+\), \(s^{\star}-\}\), and \(N_B = 20\) if tb_orbs is “sp3d5s*”, in which case the basis states are \(\{s+\), \(s-\), \(x+\), \(x-\), \(y+\), \(y-\), \(z+\), \(z-\), \(yz+\), \(yz-\), \(xz+\), \(xz-\), \(xy+\), \(xy-\), \((x^2-y^2)+\), \((x^2-y^2)-\), \((3z^2-r^2)+\), \((3z^2-r^2)-\), \(s^{\star}+\), \(s^{\star}-\}\); the matrix is partitioned into \(N_B\times N_B\) blocks.

solve(energy_target: float, k: tuple | ndarray = None) None

Solve the atomistic tight-binding Schrödinger equation.

The algorithm involves the following steps: (1) calculation of the external potential on the atomic positions, either by direct evaluation of atoms.phi or by interpolation from atoms.d, (2) construction of the tight-binding Hamiltonian matrix, and (3) partial diagonalization of this matrix. After execution, the eigenenergies and eigenfunctions are stored in atoms.energies and atoms.eigenfunctions.

Parameters:
  • energy_target (float) – The computed eigenpairs are those whose eigenenergies are closest to this energy.

  • k (tuple or Numpy.ndarray, optional) – Vector of the Cartesian coordinates of the crystal wavevector; ignored if the atomic structure does not have periodic boundary conditions. If None, set to (0., 0., 0.), corresponding to the \(\Gamma\) point in the Brillouin zone of the supercell. Default: None.

class SolverParams(inp_dict=None)

Bases: SolverParams

Parameters to pass to an atomistic tight-binding Schrödinger solver.

Attributes:
  • energy_shift_db (float) – Constant energy shift to be applied to the \(sp^3\) hybridized orbitals aligned with dangling bonds of surface atoms, emulating surface passivation. This suppresses unphysical surface states whose energies tend to lie within the bandgap. For more details, see Ref. [LOVAK04]. Values greater than 5.0*ct.e (5 eV) are recommended. Default: 9.0*ct.e (9 eV).

  • method (str) – Method used to interpolate the finite-element electric potential on the atomic positions, if applicable. The options are “nearest” for a nearest-neighbor interpolation, “linear” for a linear interpolation, and “cubic” for a cubic interpolation. For interpolations from first-order finite-element meshes, “linear” offers optimal accuracy and speed. Default: “linear”.

  • num_states (int) – Number of eigenpairs to be computed. Default: 1.

  • maxiter (int) – Deprecated and ignored solver pararameter to be removed in future versions of QTCAD.

  • rtol (float – Relative error on the eigenvalues setting the convergence criterion of the eigensolver. If 0, the eigensolver iterations run until the error on the eigenvalues reaches machine precision. Default: 1e-10.

  • memory_mode (str) – Memory mode for the eigensolver, which may be set either to "robust" or "low". The "robust" memory mode provides the highest numerical stability and is recommended for problems that may be numerically challenging. Such situations can occur, for example, in some systems with very large atomic structures or rapidly varying confinement potentials. The "low" memory mode reduces memory usage by around 40% for large atomic structures. Default: "robust".

  • memory_threshold (int, float, or None) – Memory threshold for the eigensolver’s internal data structures (in GiB) above which the eigensolver may write intermediate data to disk. This reduces memory usage, enabling simulations of larger atomic structures on systems with limited memory, but may significantly increase computation time. If 0, disk usage is disabled, which may lead to out-of-memory errors. If None, set to 75% of total system memory. Default: 0.

  • num_threads (int or None) – Number of threads over which the solver’s algorithm is parallelized. When memory_mode="low", for large atomic structures, the numerical stability of the algorithm may be improved by reducing the number of threads. If None, set to the maximum number of threads available on the system. Default: None.

  • noise (float or None) – Strength of a random tight-binding Hamiltonian perturbation used by the solver. Increasing the perturbation strength may improve numerical stability and convergence for numerically challenging problems. However, larger perturbations also increase the deviation of the computed eigenpairs from those of the unperturbed Hamiltonian. If None, an appropriate value is selected automatically depending on the solver configuration: 1e-7 * ct.e (100 neV) if memory_mode="low", 0.0 otherwise. Default: None.

  • max_retries (int) – Maximum number of times to retry the solver with different instances of the random tight-binding Hamiltonian perturbation. For each attempt, the solver checks early in the computation whether convergence to a physical solution is likely. If not, the computation is interrupted and retried with a new perturbation. Default: 10.

  • verbose (bool) – Whether information pertaining to the solver computation progression is printed. Default: False.

__init__(inp_dict=None) None
Parameters:

inp_dict (dict, optional) – Dictionary specifying certain solver parameters to be used instead of their default values.