Berry Curvature
-
double *diverge_fukui(diverge_model_t *m, complex128_t *U, index_t nb, index_t *nk)
[source] Calculate Berry’s curvature \(\Omega(\boldsymbol{k})\) using the Fukui-Hatsugai method, normed to the Chern number, i.e., the sum of all elements for a certain chern band yields the Chern number of that band, not \(2\pi\) times the Chern number.
- Parameters:
m (diverge_model_t) – model instance. obtain all parameters from there by default. internals must be set (
diverge_model_internals_common()) in order to have U initialized. if NULL is passed, the function can still operate in case all the other parameters are set accordingly.U (complex128_t*) – orbital to band matrices as (k,b,o) array. Use if != NULL.
nb (index_t) – number of bands. Use this if > 0.
nk (index_t*) – number of k points (3,) array. Use if != NULL. If
nk[0] < 0 || nk[1] < 0 || nk[2] < 0, include transformation to improper gauge in the calculation of \(\Omega(\boldsymbol{k})\) and useabs(nk[i])as number of \(\boldsymbol{k}\) points. In case the improper gauge is used, one can swap the sign convention by changing the number of negative dimensions.
- Returns:
doublearray of shape(nk, nb, 3)that contains the Berry curvature along the three crystal axes. Must be freed manually by a call tofreeordiverge_mem_free(). May beNULLon errors.
-
double *diverge_fukui_non_abelian(diverge_model_t *m, complex128_t *U, index_t nb, index_t *nk, index_t *which_bands, index_t n_which_bands)
[source] Calculate the non-abelian Berry curvature over a set of bands using Fukui’s method. As for
diverge_fukui(), we norm it to the Chern number. The input parameters also follow the functiondiverge_fukui():- Parameters:
m (diverge_model_t) – model instance. obtain all parameters from there by default. internals must be set (
diverge_model_internals_common()) in order to have U initialized. if NULL is passed, the function can still operate in case all the other parameters are set accordingly.U (complex128_t*) – orbital to band matrices as (k,b,o) array. Use if != NULL.
nb (index_t) – number of bands. Use this if > 0.
nk (index_t*) – number of k points (3,) array. Use if != NULL. If
nk[0] < 0 || nk[1] < 0 || nk[2] < 0, include transformation to improper gauge in the calculation of \(\Omega(\boldsymbol{k})\) and useabs(nk[i])as number of \(\boldsymbol{k}\) points. In case the improper gauge is used, one can swap the sign convention by changing the number of negative dimensions.which_bands (index_t*) – selection of bands to take the non-abelian determinant over
n_which_bands (index_t) – number of bands in the selection (same usage as in
diverge_qgt())
- Returns:
doublearray of shape(nk, 3)that contains the non-abelian Berry curvature along the three crystal axes. Must be freed manually by a call tofreeordiverge_mem_free(). May beNULLon errors.
-
double *diverge_qgt(diverge_model_t *m, complex128_t *U, index_t nb, index_t *nk, index_t *which_bands, index_t n_which_bands, int non_ortho_grad)
[source] Calculate the Fubini-Study metric \(g(\boldsymbol k)\). It is defined as \(g(\boldsymbol k) = \frac{1}{2} \mathrm{Tr} \partial_i P_{\mathcal S} \partial_i P_\mathcal{S}\), where \(P^{o,o'}_{\mathcal S}(\boldsymbol k) = \sum_{b\in\mathcal S} U_{o,b}(\boldsymbol k) U_{o',b}^*(\boldsymbol k)\), and \(\mathcal S\) denotes a set of bands to sum over. Our implementation only takes finite differences along each of the lattice directions, which are transformed to cartesian coordinates with
non_ortho_grad.- Parameters:
m (diverge_model_t) – the model instance. May be NULL in case all other parameters are given (non-NULL / not -1).
U (complex128_t*) – orbital to band matrices as (k,b,o) array; \(U_{o,b}(\boldsymbol k)\). May be NULL in case
mcontains common internals.nb (index_t) – total number of bands in the system. May be -1 in case
mis given.nk (index_t*) – number of k points as array of shape (3,). May be NULL in case
mis given. As fordiverge_fukui(), if any of the provided mesh lengths is negative, this function transforms to the improper gauge; the modelmmust not be NULL for this to work. In case the improper gauge is used, one can swap the sign convention by changing the number of negative dimensions.which_bands (index_t*) – the bands to sum over. Describes the set \(\mathcal S\). Must not be NULL. Array of shape (
n_which_bands,).n_which_bands (index_t) – number of bands to sum over. Describes the set \(\mathcal S\), i.e., the array
which_bands.non_ortho_grad (int) – boolean flag that determines whether the lattice vectors are taken into account in the calculation of \(\nabla f \cdot \nabla g\).
- Returns:
a
doublearray of size (nk,) with the values of \(g(\boldsymbol k)\). Must be free’d by the user by a call to free ordiverge_mem_free().
-
complex128_t *diverge_qgt_tensor(diverge_model_t *m, complex128_t *U, index_t nb, index_t *nk, index_t *which_bands, index_t n_which_bands, int non_ortho_grad)
[source] Calculate the full quantum geometric tensor \(\eta_{\mu\nu}(\boldsymbol k)\), which split into real- and imaginary parts yields the Berry curvature \(-2\mathrm{Im}\, \eta_{\mu\nu}(\boldsymbol k) = \Omega_{\mu\nu}(\boldsymbol k)\) (see
diverge_fukui_non_abelian()) and the quantum metric \(\mathrm{Re}\, \eta_{\mu\nu}(\boldsymbol k) = g_{\mu\nu}(\boldsymbol k)\) (seediverge_qgt()). Following [Resta, EPJB 79, 121-137 (2011)], we can obtain the metric tensor in a fully gauge-invariant way by calculating \(\eta_{\mu\nu}(\boldsymbol k) = \mathrm{Tr}\big[ \partial_\mu \hat P(\boldsymbol k) \hat Q(\boldsymbol k) \partial_\nu \hat P(\boldsymbol k) \big]\). The projectors are defined as \(P_{o,o'}(\boldsymbol k) = \sum_{b\in\mathcal S} U_{o,b}(\boldsymbol k) U_{o',b}^*(\boldsymbol k)\) and \(\hat Q(\boldsymbol k) = 1 - \hat P(\boldsymbol k)\), where \(\mathcal S\) denotes the set of isolated bands to calculate the quantum metric over.Note
The Berry curvature obtained from this function is not normalized intuitively. To obtain the Chern number (in a certain direction), you have to calculate
\[\mathcal C_{\mu\nu} = \frac{-2\pi}{A N_{\boldsymbol k}} \sum_{\boldsymbol k} \mathrm{Im}\big( \Omega_{\mu\nu}(\boldsymbol k) - \Omega_{\nu\mu}(\boldsymbol k)\big) \,,\]with \(A = (\boldsymbol a_1 \times \boldsymbol a_2) \cdot \boldsymbol a_3\) the unit cell area.
The quantum metric (
diverge_qgt()) is given in the same units:\[g(\boldsymbol k) = \sum_i \mathrm{Re}\big( \eta_{ii}(\boldsymbol k) \big) \,.\]- Parameters:
m (diverge_model_t) – the model instance. May be NULL in case all other parameters are given (non-NULL / not -1).
U (complex128_t*) – orbital to band matrices as (k,b,o) array; \(U_{o,b}(\boldsymbol k)\). May be NULL in case
mcontains common internals.nb (index_t) – total number of bands in the system. May be -1 in case
mis given.nk (index_t*) – number of k points as array of shape (3,). May be NULL in case
mis given. As fordiverge_fukui(), if any of the provided mesh lengths is negative, this function transforms to the improper gauge; the modelmmust not be NULL for this to work. In case the improper gauge is used, one can swap the sign convention by changing the number of negative dimensions.which_bands (index_t*) – the bands to sum over. Describes the set \(\mathcal S\). Must not be NULL. Array of shape (
n_which_bands,).n_which_bands (index_t) – number of bands to sum over. Describes the set \(\mathcal S\), i.e., the array
which_bands.non_ortho_grad (int) – boolean flag that determines whether the lattice vectors are taken into account in the calculation of \(\nabla f \cdot \nabla g\).
- Returns:
a
complex128_tarray of size (nk,3,3) with the values of \(\eta_{\mu\nu}(\boldsymbol k)\). Must be free’d by the user by a call to free ordiverge_mem_free().