pythtb.TBModel.velocity#
- TBModel.velocity(k_pts, cartesian=False, flatten_spin_axis=False, *, param_periods=None, diff_scheme='central', diff_order=2, **params)[source]#
Generate the velocity operator in the orbital basis.
The velocity operator is related to the derivative of the Hamiltonian with respect to each reciprocal lattice direction, i.e.,
\[v_{\mu}(k) = \hbar \frac{\partial H(k)}{\partial k_{\mu}}\]When passing parameter sweeps via
**params, the generalized velocity operator is computed by appending finite-difference derivatives of the Hamiltonian with respect to the swept parameters.Added in version 2.0.0.
- Parameters:
- k_pts(Nk, dim_k) numpy.ndarray
Reduced k-points where the velocity operator is evaluated. Must be a 2D array of shape
(Nk, dim_k), wheredim_kis the number of periodic directions in the model.- cartesianbool, optional
If True, use Cartesian coordinates for the velocity operator, otherwise derivatives are taken with respect to reduced coordinates.
- flatten_spin_axisbool, optional
If True, the spin indices are flattened into the orbital indices. This results in a velocity operator of shape
(..., norb*nspin, norb*nspin). If False (default), the velocity operator has shape(..., norb, nspin, norb, nspin).- param_periodsdict[str, float], optional
Optional map
{param_name: period}for swept parameters. When supplied, assumes the parameter is cyclic and trims any duplicated endpoints, or endpoints equal to the start plus the given period, before building finite-difference stencils. This can improve numerical accuracy by using centered differences throughout the parameter range. Otherwise, the function will use a backward difference at the endpoint and a forward difference at the start.- diff_schemestr, optional
Finite difference scheme to use for parameter derivatives. Options are “central” (default) or “forward”. This parameter is only relevant when passing varying parameters.
- diff_orderint, optional
Order of accuracy for finite difference lambda derivatives. Must be an even integer for “central” scheme (default is
4), and a positive integer for “forward” scheme. This parameter is only relevant when passing varying parameters.- **params
Parameter assignments. Scalars are applied directly; any 1D array/list is treated as a sweep and automatically adds a finite-difference derivative \(\partial_{\lambda} H\) for that parameter. The velocity operator is evaluated at all combinations of parameter values.
- Returns:
- velnumpy.ndarray
Velocity operator in the orbital basis. First axis indexes the cartesian direction if
cartesian=True. Otherwise, it indexes the reduced direction. Ifinclude_lambda=True, the lambda (parameter) derivatives are appended after the k-directions along the first axis.Shape is:
(n_dir, Nk, *param_shape, norb, norb)for spinless models,(n_dir, Nk, *param_shape, norb, 2, norb, 2)for spinful models.(..., norb*nspin, norb*nspin)ifflatten_spin_axis=True.
where
n_dir = dim_k + n_params, wheren_paramsis the number of parameters being swept over.
Notes
We use units where \(\hbar = 1\), and thus the velocity operator is simply defined as the gradient of the Hamiltonian with respect to \(\mathbf{k}\) or \(\boldsymbol{\lambda}\).
The velocity operator is computed in tight-binding convention I, which includes phase factors associated with orbital positions in the hopping terms.
For the k-derivatives, if
cartesian=True, the velocity operator is given by the derivative with respect to Cartesian \(\mathbf{k}\)-coordinates:\[v_\alpha(\mathbf{k}) = \frac{\partial H(\mathbf{k})}{\partial k_\alpha} = \sum_{\mathbf{R}} t_{ij}(\mathbf{R}) \, i(\mathbf{r}_i - \mathbf{r}_j + \mathbf{R})_{\alpha} \, \exp[i \mathbf{k} \cdot (\mathbf{r}_i - \mathbf{r}_j + \mathbf{R})]\]where \(t_{ij}(\mathbf{R})\) are the hopping amplitudes, \(\mathbf{r}_i\) and \(\mathbf{r}_j\) are the orbital positions in Cartesian coordinates, and \(\mathbf{R}\) are the lattice vectors in Cartesian coordinates.
For the k-derivatives, if
cartesian=False, the velocity operator is given by the derivative with respect to reduced \(\mathbf{\kappa}\)-coordinates:\[v_\alpha(\mathbf{\kappa}) = \frac{\partial H(\mathbf{\kappa})}{\partial \kappa_\alpha} = \sum_{\mathbf{R}} t_{ij}(\mathbf{R}) \, i 2 \pi (\boldsymbol{\tau_i} - \boldsymbol{\tau_j} + \mathbf{R})_{\alpha} \, \exp[i 2 \pi \mathbf{\kappa} \cdot (\boldsymbol{\tau_i}- \boldsymbol{\tau_j} + \mathbf{R})]\]where \(\boldsymbol{\tau_i}\) and \(\boldsymbol{\tau_j}\) are the orbital positions in reduced coordinates, \(\mathbf{\kappa}\) are the k-points in reduced coordinates, and \(\mathbf{R}\) are the lattice vectors in reduced coordinates.
Passing a list/array for a parameter means you want derivatives with respect to that parameter. If the intent is simply to evaluate at a specific value, resolve the symbol first via
set_parameters(), or simply pass a scalar value with**params.When passing a list/array for a parameter, the finite difference derivatives are computed explicitly as
\[\frac{\partial H}{\partial \lambda} \approx \sum_{m} c_m H(\lambda + m \Delta \lambda)\]where the coefficients \(c_m\) depend on the finite difference scheme and order.
Examples
Compute the velocity operator at the Gamma point:
>>> vel = tb.velocity(np.array([[0.0, 0.0]]))
Compute the velocity operator at several k-points with a parameter sweep. This will compute the velocity operator at all values of
mA = 0.0, 1.0, 2.0and the first axis will have length equal todim_k + 1, with the last slice corresponding to the finite-difference derivative with respect tomA.>>> vel = tb.velocity( ... np.array([[0.0, 0.0], [0.5, 0.5]]), ... mA=np.linspace(0, np.pi, 10, endpoint=False) ... )
If
mAis a periodic parameter with period2*pi, and2*piis included in the parameter list, we can inform the velocity function to trim the duplicated endpoint before building the finite-difference stencil. This can improve numerical accuracy by using centered differences throughout the parameter range. Otherwise, the function will use a backward difference at the endpoint and a forward difference at the start.Specify this by passing a dictionary to the
param_periodsargument:>>> vel = tb.velocity( ... np.array([[0.0, 0.0]]), ... mA=np.linspace(0, 2*np.pi, 10, endpoint=True), ... param_periods={"mA": 2*np.pi} ... )