Dear Colleagues, (sorry, this is a repost of the same question
to a new thread)
I have a taks to compute local density of states at a single
point for a large homogeneous sample with narrow STS tip potential
and in magnetic field. I have tried several methods in Kwant to
do this:
1) Naive diagonalization of H for system with no leads and direct
calculation of LDOS. It works, but not for large systems, so, I
see strong finite-size effects.
2) Sparse Lanczos method with several eigenvalues/functions
extracted near each point in the grid of energy values.
3) KPM method. I am not happy with the energy resolution I can
get with it.
4) Take a smaller main sample (with the size of the tip
potential), but avoid the finite-size effects by attaching a lot
of leads pointing in , e.g. 6 directions. Then, use the kwant
ldos function to scan LDOS over a grid of energies. Use
magnetic_gauge to implement B field in both sample and scattering
region.
I see the last possibility as the quickest, but it gives me
something that seems wrong to me.
Does kwant ldos function work correctly if all the leads are
insulating for a given energy? Does it correctly catch the
localized states in the scattering region?
Thank you for any feedback,
Sergey
Below is a copy of a reply by Pablo Piskunow
Dear Sergey, In terms of scaling, the most convenient is the KPM method, since it scales linearly with the inverse energy resolution (that is, the number of moments), and linearly with the system size. Could you clarify what is the issue with the approach 3)? I am not sure what is the energy resolution that you want to achieve. You can conveniently set this value when creating a `kwant.kpm.SpectralDensity` instance via the arguments `energy_resolution` or (exclusive) `num_moments`. The latter is related to the energy resoution by `\delta \pi / N`, where `\delta` is the full width of the spectrum, and `N` the size of your system. In the case of a 2D, that will be similar to `L*total number of orbitals* defined by the `where` function, that is, sites times orbitals per site. As you can see, the `kwant.kpm` module is the most suited for this problem, specially when the sample is very large. I hope this helps. Best regards, Pablo2`, where `L` is the linear size. Furthermore, you could progressively increase the energy resolution by adding moments: ``` spectrum = kwant.kpm.SpectralDensity(...) spectrum.add_moments(...) ``` If you want to resolve individual energy levels then the approach 1) and 3) will have the same scaling, however, the KPM method will not give you eigenvalues. Finally, since you want to get the LDOS at a single site or a small set of sites near the STS tip, you should use the `kwant.kpm.LocalVectors` vector factory, setting the `where` argument to the desired spot. ``` def center(site): return site.tag == (0, 0) vector_factory = kwant.kpm.LocalVectors(syst, where=center) spectrum = kwant.kpm.SpectralDensity(syst, num_moments=100, num_vectors=None, vector_factory=vector_factory) ``` Note that `num_vectors=None` will let the `kwant.kpm` module to figure out how many vectors does the vector factory produce. Otherwise, it should be at most the
n the meantime, you can create a `spectrum` instance, and evaluate the KPM expansion at any energy,