zerothi / sisl

Electronic structure Python package for post analysis and large scale tight-binding DFT/NEGF calculations
https://zerothi.github.io/sisl
Mozilla Public License 2.0
181 stars 58 forks source link

sisl.physics.hamiltonian support slice operation or not? #650

Closed AsymmetryChou closed 10 months ago

AsymmetryChou commented 10 months ago

Describe the issue Dear developers:

I use sisl.physics.hamiltonian in TB model calculation. It seems that in sisl the hamiltonian matrix element has to be given one by one. If I use slice operation as follows:

 Hamil_sisl[orb_a,orb_first_b:orb_last_b]=hamil_block[orb_a-orb_first_a,:]

there comes the error:

File "/xxxx/python3.9/site-packages/sisl/sparse_geometry.py", line 1630, in __setitem__
    self._csr[key] = val
  File "/xxxx/python3.9/site-packages/sisl/sparse.py", line 1252, in __setitem__
    index = self._extend(i, j)
  File "/xxxx/python3.9/site-packages/sisl/sparse.py", line 886, in _extend
    j = asarrayi(j).ravel()
TypeError: int() argument must be a string, a bytes-like object or a number, not 'slice'

My question: Is there any faster operation helping me give the hamiltonian matrix element to Hamil_sisl, something like slice operation in numpy ?

Because my hamiltonian matrix element is determined by some other code and tranlated into sisl.physics.hamiltonian for TBtrans input, it seems to be unconvenient to use H.constrcut or H.tile method to construct Hamiltonian in sisl. If I can do slice operation to give values to Hamil_sisl, it would be best~

Thank you!

Version details Run the below code and add to issue (if an issue is relevant for the issue):

import sys
print(sys.version)
import sisl
print(sisl.__version__)

3.9.18 (main, Sep 11 2023, 13:41:44) 
[GCC 11.2.0]
0.14.3.dev54+g83feb814c
zerothi commented 10 months ago

Thanks for opening this issue.

Indeed that is a bug, it should be fixed. However, if what you want to do is something like:

sisl.Hamiltonian[:, :] = hamil_block

Then you can more easily do it via something like this:

import scipy.sparse as sps
csr = sps.csr_matrix(hamil_block)
H = sisl.Hamiltonian.fromsp(geometry, csr)

it should also be much faster.

AsymmetryChou commented 10 months ago

Thanks for your reply!

I would take scipy.sparse to my code. In this method, how should I label the lattice vector to describe the interaction between unit cells?

For now I do this by

H[0,1,(0,0,1)] = hopping

to describe the interaction between the first orbital in unit cell(0,0,0) and the second orbital in unit cell(0,0,1)

When using the new method, where should I label this information?

import scipy.sparse as sps
csr = sps.csr_matrix(hamil_block)
H = sisl.Hamiltonian.fromsp(geometry, csr)

PS: hamil_block is the interaction between atom A's all orbtials and atom B's all orbitals. The Hamiltonian is in real-space representation.

zerothi commented 10 months ago

Internally this is represented by offsets, for instance:

H[0, 1, (0, 0, 1)] = hopping
# is equivalent to
off = H.geometry.sc_index([0, 0, 1]) * H.geometry.no
H[0, 1 + off] = hopping

Hence your sparse matrix can be constructed by simple means of appending various CSR matrices.

Which code are you trying to extract the information from?

AsymmetryChou commented 10 months ago

Thank you for your kind help!

My friends and I are trying to design a neural network to predict the TB hamiltonian for some materials and calculate their transport properties by TBtrans.

zerothi commented 10 months ago

Sounds cool! :)

AsymmetryChou commented 10 months ago

Sounds cool! :)

Thanks~
Hope we could literally make something interesting!

zerothi commented 10 months ago

This should hopefully be fixed in the latest commit, try it out