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