1+ from __future__ import annotations
2+
13import numpy as np
24import tqdm
3- from typing import Callable , Optional
5+ from typing import Callable , Optional , Sequence
46
5- from sisl import BrillouinZone , DensityMatrix , get_distribution , unit_convert
7+ from sisl import BrillouinZone , DensityMatrix , Hamiltonian , EigenstateElectron , get_distribution , unit_convert
68from ._compute_dm import add_cnc_diag_spin , add_cnc_nc
79
8- def compute_dm (bz : BrillouinZone , occ_distribution : Optional [Callable ] = None ,
9- occtol : float = 1e-9 , fermi_dirac_T : float = 300. , eta : bool = True ):
10+ def compute_dm (bz : BrillouinZone , eigenstates : Optional [Sequence [EigenstateElectron | Sequence [EigenstateElectron ]]] = None ,
11+ occ_distribution : Optional [Callable ] = None , occtol : float = 1e-9 ,
12+ fermi_dirac_T : float = 300. , eta : bool = True ):
1013 """Computes the DM from the eigenstates of a Hamiltonian along a BZ.
1114
1215 Parameters
1316 ----------
1417 bz: BrillouinZone
1518 The brillouin zone object containing the Hamiltonian of the system
1619 and the k-points to be sampled.
20+ eigenstates: list of EigenstateElectron, optional
21+ The already calculated eigenstates for the bz. If not given, they will
22+ be calculated from the Hamiltonian associated with the bz. If the calculation
23+ is spin polarized a list with one list of eigenstates for each spin component
24+ should be passed.
1725 occ_distribution: function, optional
1826 The distribution that will determine the occupations of states. It will
1927 receive an array of energies (in eV, referenced to fermi level) and it should
@@ -29,8 +37,10 @@ def compute_dm(bz: BrillouinZone, occ_distribution: Optional[Callable] = None,
2937 eta: bool, optional
3038 Whether a progress bar should be displayed or not.
3139 """
40+ provided_eigenstates = eigenstates
41+
3242 # Get the hamiltonian
33- H = bz .parent
43+ H : Hamiltonian = bz .parent
3444
3545 # Geometry
3646 geom = H .geometry
@@ -76,7 +86,12 @@ def compute_dm(bz: BrillouinZone, occ_distribution: Optional[Callable] = None,
7686 # Loop over spins
7787 for ispin in spin_iterator :
7888 # Create the eigenstates generator
79- eigenstates = bz .apply .eigenstate (spin = ispin )
89+ if provided_eigenstates is None :
90+ eigenstates = bz .apply .eigenstate (spin = ispin )
91+ else :
92+ eigenstates = provided_eigenstates
93+ if DM .spin .is_polarized :
94+ eigenstates = eigenstates [ispin ]
8095
8196 # Zip it with the weights so that we can scale the contribution of each k point.
8297 k_it = zip (bz .weight , eigenstates )
0 commit comments