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^2`, 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 *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,
Pablo