kwant issueshttps://gitlab.kwant-project.org/kwant/kwant/-/issues2024-01-09T20:52:24Zhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/330be more systematic about use of random numbers within the tests2024-01-09T20:52:24ZJoseph Westonbe more systematic about use of random numbers within the testsKwant's test suite has flaky test failures. I do not believe that these failures are "bad" (i.e. they do not correspond to bugs in kwant) but they are not reproducible. I believe that this is because some of the tests rely on numpy's RNG...Kwant's test suite has flaky test failures. I do not believe that these failures are "bad" (i.e. they do not correspond to bugs in kwant) but they are not reproducible. I believe that this is because some of the tests rely on numpy's RNG, and we do not set the seed in a consistent way.
I know for a fact that some of the tests in `kwant.tests.test_qsymm` directly use numpy RNG, but even if other tests do not explicitly use it, the numpy RNG is sometimes used inconspicuously (e.g. during sparse diagonalization to choose the initial vector).
My proposal is to simply enable [pytest-randomly](https://pypi.org/project/pytest-randomly/) in CI, so that at least the CI tests are reproducible.
If we also want people to be able to run the tests in a reproducible way on their own computers then we should also make pytest-randomly a testing dependencyhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/428wraparound: cryptic error message when k_x, k_y, ... not provided2023-06-30T16:27:24ZChristoph Grothwraparound: cryptic error message when k_x, k_y, ... not providedEvaluating the Hamiltonian of a wrapped-around system without providing the required momenta parameters leads to an error message that is inscrutable even for advanced users of Kwant. For example, executing the following piece of code (...Evaluating the Hamiltonian of a wrapped-around system without providing the required momenta parameters leads to an error message that is inscrutable even for advanced users of Kwant. For example, executing the following piece of code (only the last line differs from https://kwant-project.org/doc/1/pre/whatsnew/1.3#finalizing-builders-with-multiple-translational-symmetries)
```python
from matplotlib import pyplot
import kwant
lat = kwant.lattice.honeycomb()
sym = kwant.TranslationalSymmetry(lat.vec((1, 0)), lat.vec((0, 1)))
bulk = kwant.Builder(sym)
bulk[ [lat.a(0, 0), lat.b(0, 0)] ] = 0
bulk[lat.neighbors()] = 1
wrapped = kwant.wraparound.wraparound(bulk).finalized()
ham = wrapped.hamiltonian_submatrix()
```
The above code can be fixed by changing the last line to
```python
ham = wrapped.hamiltonian_submatrix(params=dict(k_x=0, k_y=0))
```
but the problem is the unhelpful error message produced by the original snippet:
```
/home/cwg/wo/11/kwant-src/kwant/lattice.py:120: KwantDeprecationWarning: Not specfying norbs is deprecated. Always specify norbs when creating site families.
self.sublattices = [Monatomic(prim_vecs, offset, sname, norb)
Traceback (most recent call last):
File "/home/cwg/wo/11/kwant-src/kwant/builder.py", line 1815, in hamiltonian
value = value(site_i, site_j, *args)
File "/home/cwg/wo/11/kwant-src/kwant/wraparound.py", line 135, in f
acc = acc + val(*out_args)
File "/home/cwg/wo/11/kwant-src/kwant/wraparound.py", line 115, in f
phase = cmath.exp(1j * ta.dot(elem, args[mnp:]))
TypeError: Expecting a number.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/cwg/wo/11/kwant-src/test2.py", line 11, in <module>
ham = wrapped.hamiltonian_submatrix()
File "/home/cwg/wo/11/kwant-src/kwant/_common.py", line 73, in inner
return f(*args, **kwargs)
File "kwant/_system.pyx", line 324, in kwant._system.hamiltonian_submatrix
mat = func(ham, args, params, self.graph, diag, to_norb, to_off,
File "kwant/_system.pyx", line 223, in kwant._system.make_dense_full
h = mat = matrix(ham(ts, fs, *args, params=params), complex)
File "/home/cwg/wo/11/kwant-src/kwant/builder.py", line 1823, in hamiltonian
_raise_user_error(exc, value)
File "/home/cwg/wo/11/kwant-src/kwant/builder.py", line 1719, in _raise_user_error
raise UserCodeError(msg.format(func.__name__)) from exc
kwant._common.UserCodeError: Error occurred in user-supplied value function "f".
See the upper part of the above backtrace for more information.
```https://gitlab.kwant-project.org/kwant/kwant/-/issues/337Docstrings of __call__ are not rendered in HTML documentation2023-06-01T08:42:43ZJoseph WestonDocstrings of __call__ are not rendered in HTML documentationSee for example the [`Bands` documentation](https://kwant-project.org/doc/1/reference/generated/kwant.physics.Bands#kwant.physics.Bands).
In the docstring of `__call__` we actually specify how to call an instance of `Bands`, and specify...See for example the [`Bands` documentation](https://kwant-project.org/doc/1/reference/generated/kwant.physics.Bands#kwant.physics.Bands).
In the docstring of `__call__` we actually specify how to call an instance of `Bands`, and specify some extra restrictions on the API (e.g. that the return order is ascending in energy).
I would be surprised if we were the first people to encounter the problem of needing to document callable objects properly. This will probably involve configuring sphinx in some esoteric way, or putting the `__call__` docstring in the class docstring in such a way that sphinx displays it nicely.https://gitlab.kwant-project.org/kwant/kwant/-/issues/392Kwant discretizer fails when expression includes sqrt(parameter)2023-05-05T17:45:01ZAndré MeloKwant discretizer fails when expression includes sqrt(parameter)This code
```python
import kwant.continuum
ham = "sqrt(1 - B_x) * kron(sigma_0, sigma_x)"
kwant.continuum.discretizer.discretize(ham, coords=['x'])
```
fails with the following traceback
```python
TypeError ...This code
```python
import kwant.continuum
ham = "sqrt(1 - B_x) * kron(sigma_0, sigma_x)"
kwant.continuum.discretizer.discretize(ham, coords=['x'])
```
fails with the following traceback
```python
TypeError Traceback (most recent call last)
<ipython-input-4-c24dd4d4768b> in <module>
1 import kwant.continuum
2 ham = "sqrt(1 - B_x) * kron(sigma_0, sigma_x)"
----> 3 kwant.continuum.discretizer.discretize(ham, coords=['x'])
/opt/conda/lib/python3.8/site-packages/kwant/continuum/discretizer.py in discretize(hamiltonian, coords, grid, locals, grid_spacing)
140 """
141 tb, coords = discretize_symbolic(hamiltonian, coords, locals=locals)
--> 142 return build_discretized(tb, coords, grid=grid, grid_spacing=grid_spacing)
143
144
/opt/conda/lib/python3.8/site-packages/kwant/continuum/discretizer.py in build_discretized(tb_hamiltonian, coords, grid, locals, grid_spacing)
348 name = 'hopping_{}'.format(n)
349
--> 350 tb[offset] = _builder_value(hopping, coords, np.diag(lat.prim_vecs),
351 onsite, name)
352
/opt/conda/lib/python3.8/site-packages/kwant/continuum/discretizer.py in _builder_value(expr, coords, grid_spacing, onsite, name)
643 expr = expr.subs({_displacements[c]: grid_spacing[n]
644 for n, c in enumerate(coords)})
--> 645 return_string, map_func_calls, const_symbols, _cache = _return_string(
646 expr, coords=coords)
647
/opt/conda/lib/python3.8/site-packages/kwant/continuum/discretizer.py in _return_string(expr, coords)
579 # which will be assigned to '_cache_n' in the function body.
580 mons = monomials(expr, expr.atoms(sympy.Symbol))
--> 581 mons = {k: cache(v) for k, v in mons.items()}
582 mons = ["{} * {}".format(_print_sympy(k), _print_sympy(v))
583 for k, v in mons.items()]
/opt/conda/lib/python3.8/site-packages/kwant/continuum/discretizer.py in <dictcomp>(.0)
579 # which will be assigned to '_cache_n' in the function body.
580 mons = monomials(expr, expr.atoms(sympy.Symbol))
--> 581 mons = {k: cache(v) for k, v in mons.items()}
582 mons = ["{} * {}".format(_print_sympy(k), _print_sympy(v))
583 for k, v in mons.items()]
/opt/conda/lib/python3.8/site-packages/kwant/continuum/discretizer.py in cache(x)
559 def cache(x):
560 s = sympy.symbols('_cache_{}'.format(len(_cache)))
--> 561 _cache[str(s)] = ta.array(x.tolist(), complex)
562 return s
563
/opt/conda/lib/python3.8/site-packages/sympy/core/expr.py in __complex__(self)
330 result = self.evalf()
331 re, im = result.as_real_imag()
--> 332 return complex(float(re), float(im))
333
334 def _cmp(self, other, op, cls):
/opt/conda/lib/python3.8/site-packages/sympy/core/expr.py in __float__(self)
325 if result.is_number and result.as_real_imag()[1]:
326 raise TypeError("can't convert complex to float")
--> 327 raise TypeError("can't convert expression to float")
328
329 def __complex__(self):
TypeError: can't convert expression to float
```
The same piece of code works if I replace the `sqrt` with other functions such as `sin`, `cos`, etc.
Part of the problem seems to be that square roots are not caught by this segment in [kwant.continuum.discretizer._return_string](https://gitlab.kwant-project.org/kwant/kwant/-/blob/master/kwant/continuum/discretizer.py#L571-573):
```python
map_func_calls = expr.atoms(AppliedUndef, sympy.Function)
map_func_calls = {s: sympy.symbols('_const_{}'.format(n))
for n, s in enumerate(map_func_calls)}
```
That's because square roots in sympy [are `sympy.Pow` objects and not `sympy.Function`](https://github.com/sympy/sympy/blob/777a76d3cb06da144d1b13e2183353f34a6d09f8/sympy/functions/elementary/miscellaneous.py#L154):
```python
isinstance(sympy.sqrt(1-sympy.Symbol('B_x')), sympy.Function)
>>> False
```
However, just adding `sympy.Pow` to the `expr.atoms` call doesn't solve the problem.https://gitlab.kwant-project.org/kwant/kwant/-/issues/424Wrong example in `kwant.kpm.conductivity` docstring2023-04-19T21:01:55ZDániel VarjasWrong example in `kwant.kpm.conductivity` docstringThe example given in the docstring of `kwant.kpm.conductivity` gives nonsense result. Should use the example in the [tutorial](https://kwant-project.org/doc/dev/tutorial/kpm) instead. The tutorial example uses KPM vectors deep in the bul...The example given in the docstring of `kwant.kpm.conductivity` gives nonsense result. Should use the example in the [tutorial](https://kwant-project.org/doc/dev/tutorial/kpm) instead. The tutorial example uses KPM vectors deep in the bulk, while the docstring example uses random vectors everywhere, giving a poorly averaged result with the default 10 random vectors.https://gitlab.kwant-project.org/kwant/kwant/-/issues/422Option to change svd LAPACK driver2023-02-28T11:10:15ZRik BroekhovenOption to change svd LAPACK driverDefault SVD lapack driver is "gessd" which in some cases can fail to find the SVD decomposition of the hopping in `kwant.self_energy`. It would be good to have a user option to change the driver to "gesvd" which is less efficient but mor...Default SVD lapack driver is "gessd" which in some cases can fail to find the SVD decomposition of the hopping in `kwant.self_energy`. It would be good to have a user option to change the driver to "gesvd" which is less efficient but more complete.https://gitlab.kwant-project.org/kwant/kwant/-/issues/235Mumps support for Windows conda builds2022-08-03T07:41:24ZJoseph WestonMumps support for Windows conda buildsBlocked by [this upstream MR](https://github.com/conda-forge/mumps-feedstock/pull/28/)Blocked by [this upstream MR](https://github.com/conda-forge/mumps-feedstock/pull/28/)https://gitlab.kwant-project.org/kwant/kwant/-/issues/408module 'kwant.linalg._mumps' has no attribute 'dmumps'2021-10-06T11:05:07ZBhavya Bhardwajmodule 'kwant.linalg._mumps' has no attribute 'dmumps'Python Version: 3.7.8
Kwant Version: 1.4.2
```
Error--------
AttributeError Traceback (most recent call last)
<ipython-input-6-c80da766c4bb> in <module>
17 pyplot.ylabel("conductance [e^2/h]")
1...Python Version: 3.7.8
Kwant Version: 1.4.2
```
Error--------
AttributeError Traceback (most recent call last)
<ipython-input-6-c80da766c4bb> in <module>
17 pyplot.ylabel("conductance [e^2/h]")
18 pyplot.show()
---> 19 solving(model.tokwant())
<ipython-input-6-c80da766c4bb> in solving(sys)
7 energy = ie * 0.01
8 # compute the scattering matrix at a given energy
----> 9 smatrix = kwant.greens_function(sys, energy,check_hermiticity=False)
10 # compute the transmission probability from lead 0 to
11 # lead 1
~/Downloads/112358/lib/python3.7/site-packages/kwant/_common.py in inner(*args, **kwargs)
70 if sig.bind(*args, **kwargs).arguments.get(parameter_name):
71 warn()
---> 72 return f(*args, **kwargs)
73
74 return inner
~/Downloads/112358/lib/python3.7/site-packages/kwant/solvers/common.py in greens_function(self, sys, energy, args, out_leads, in_leads, check_hermiticity, params)
485 rhs = sp.bmat([[i for i in linsys.rhs if i.shape[1]]],
486 format=self.rhsformat)
--> 487 flhs = self._factorized(linsys.lhs)
488 data = self._solve_linear_sys(flhs, rhs, kept_vars)
489
~/Downloads/112358/lib/python3.7/site-packages/kwant/solvers/mumps.py in _factorized(self, a)
102 def _factorized(self, a):
103 inst = mumps.MUMPSContext()
--> 104 inst.factor(a, ordering=self.ordering)
105 return inst
106
~/Downloads/112358/lib/python3.7/site-packages/kwant/linalg/mumps.py in factor(self, a, ordering, ooc, pivot_tol, reuse_analysis, overwrite_a)
318 row, col, data)
319 else:
--> 320 self.analyze(a, ordering=ordering, overwrite_a=overwrite_a)
321
322 self.mumps_instance.icntl[22] = 1 if ooc else 0
~/Downloads/112358/lib/python3.7/site-packages/kwant/linalg/mumps.py in analyze(self, a, ordering, overwrite_a)
227
228 if dtype != self.dtype:
--> 229 self.mumps_instance = getattr(_mumps, dtype+"mumps")(self.verbose)
230 self.dtype = dtype
231
*AttributeError: module 'kwant.linalg._mumps' has no attribute 'dmumps'*
```https://gitlab.kwant-project.org/kwant/kwant/-/issues/404StabilizedModes.sqrt_hop scaling and off-diagonal entries change when adding ...2021-03-30T11:57:50ZDavid van DrielStabilizedModes.sqrt_hop scaling and off-diagonal entries change when adding lead_conservation lawsI multiply StabilizedModes.vecs by StabilizedModes.sqrt_hop (H.C.) to get a matrix related to the incoming lead modes. But sqrt_hop behaves very differently when I add a lead_conservation law like spin or particle-hole. The scaling and o...I multiply StabilizedModes.vecs by StabilizedModes.sqrt_hop (H.C.) to get a matrix related to the incoming lead modes. But sqrt_hop behaves very differently when I add a lead_conservation law like spin or particle-hole. The scaling and off-diagonal elements are very different to what I expect. See this minimal example: [sqrt_hop_snip.py](/uploads/4d8aca2e4a9b1ec332db14eb583d8944/sqrt_hop_snip.py)
What is should I expect from sqrt_hop upon adding a lead_conservation law?https://gitlab.kwant-project.org/kwant/kwant/-/issues/378support finalization and attaching of ND systems2021-03-01T21:08:14ZAnton Akhmerovsupport finalization and attaching of ND systems### Current status
- Vectorized low level systems store similar sites in `SiteArray`s, and similar terms of the Hamiltonian in `syst.terms`.
- With respect to translation symmetries, the [data format](https://gitlab.kwant-project.org/kw...### Current status
- Vectorized low level systems store similar sites in `SiteArray`s, and similar terms of the Hamiltonian in `syst.terms`.
- With respect to translation symmetries, the [data format](https://gitlab.kwant-project.org/kwant/kwant/-/blob/master/kwant/system.py#L549-551) of terms is correct (each term stores the associated symmetry element),
- Finalization [uses](https://gitlab.kwant-project.org/kwant/kwant/-/blob/master/kwant/builder.py#L2813-2826) site ordering enforced by the interface. This is impossible or hard to generalize symmetries that are more than 1D.
- When attaching a lead we compute the [interface](https://gitlab.kwant-project.org/kwant/kwant/-/blob/master/kwant/builder.py#L1458-1463)—sites that are connected to the lead by a hopping.
- A finalized system stores [`lead_interfaces`](https://gitlab.kwant-project.org/kwant/kwant/-/blob/master/kwant/system.py#L637-639)—the indices of its low level sites that match the indices of the extra sites of the lead *in the same order*.
### Goals
- We want to be able to finalize systems with ND translations, and therefore we won't be able to enforce a specific ordering on the sites.
- We still want to be able to attach the leads (duh).
- At this point we want to keep the logic of builder the same (attaching leads by flood fill).
### Proposal
I think the apparent incompatibility between the goals is achieved by this format change:
~~Change `lead_interfaces` to be a mapping between the scattering region sites and the lead sites that only includes the sites that are connected by a hopping, instead of relying on the ordering of the sites in the infinite system.~~
Change `lead_interfaces` to be a 2D array of site numbers in the scattering region that correspond to specific sites in the lead unit cell upon translation by `k` symmetry vectors of the lead. In other words if `interface[n, k] == i`, that means that `i`'th site of the scattering region corresponds to the `n`'th site of the lead upon translation by `k+1` lead symmetry vectors that aren't shared by the system. A value of `-1` in the interface indicates that there is no site in the system that corresponds to the `n`'th site of the lead upon translation by `k+1` lead symmetry vectors. Finally, `interface.shape == (N_lead_sites, max_hopping_range)`.
1. This means that we finalize the systems without taking the interface into account (already a simplification), and have the same ordering of sites regardless of how the lead was attached.
2. When computing the new format for the `lead_interfaces` we only need a single lookup (something like `searchsorted`).
3. In principle this means that attaching a 2D lead to a 1D scattering region becomes legal (although we must specify which generator to use for the remaining 1D symmetry).vectorizationhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/402Plotly 3D system plot doesn't respect aspect ratio2021-02-22T09:20:26ZBas NijholtPlotly 3D system plot doesn't respect aspect ratioPlotting this system
![image](/uploads/9e1329603b4f870a6a1d07a3d0f3814d/image.png)
using plotly results in
![image](/uploads/e5833c722d7db53feb87b70d617d5fd8/image.png)
I tried fixing it by setting the `aspectratio` on the `fig.layout...Plotting this system
![image](/uploads/9e1329603b4f870a6a1d07a3d0f3814d/image.png)
using plotly results in
![image](/uploads/e5833c722d7db53feb87b70d617d5fd8/image.png)
I tried fixing it by setting the `aspectratio` on the `fig.layout.scene` setter but that didn't work. Possibly we are running into this upstream issue https://github.com/plotly/plotly.py/issues/2511.
I managed to fix it by setting the bounding box as suggested by @anton-akhmerov:
```python
coord_min = np.min([np.nanmin(d[key].astype(float)) for d in fig.data for key in "xyz"])
coord_max = np.max([np.nanmax(d[key].astype(float)) for d in fig.data for key in "xyz"])
lim = np.abs([coord_min, coord_max]).max()
lims = dict(range=[-lim, lim])
fig.update_layout(scene=dict(xaxis=lims, yaxis=lims, zaxis=lims))
```
I was using latest `master`.https://gitlab.kwant-project.org/kwant/kwant/-/issues/400Missing imaginary unit from the definition of the source operator2021-01-26T20:39:46ZJakub ZeleznyMissing imaginary unit from the definition of the source operatorAs far as I can say, in the documentation for the Source operator, an imaginary unit is missing in the definition: the expression given in the documentation should be multiplied by i. This should be there because otherwise the commutator...As far as I can say, in the documentation for the Source operator, an imaginary unit is missing in the definition: the expression given in the documentation should be multiplied by i. This should be there because otherwise the commutator would not be Hermitian. In the source code the commutator is in fact multiplied by i, if I'm understanding it correctly.
I also don't understand why is a Hermitian conjugate of the H_i taken for the definition of the source operator. Shouldn't the Hamiltonian matrix be Hermitian?https://gitlab.kwant-project.org/kwant/kwant/-/issues/399Basic pretty printing of systems is confusing2020-12-11T22:12:48ZChristoph GrothBasic pretty printing of systems is confusingIn bab68fe78033a2316b81883597ddf34c98c5f76c a method `System.__str__` was added that produces output like:
```
<InfiniteSystem with 4 sites, and 6 hoppings>
```
This feature went under my radar, but today I became aware (thanks to a con...In bab68fe78033a2316b81883597ddf34c98c5f76c a method `System.__str__` was added that produces output like:
```
<InfiniteSystem with 4 sites, and 6 hoppings>
```
This feature went under my radar, but today I became aware (thanks to a confused user of Kwant) that it's problematic. What is actually shown are the values of `self.graph.num_nodes` and `self.graph.num_edges`. This poses several problems:
- Hoppings of Kwant systems are by design Hermitian. In order to be able to query the hoppings of each site, each hopping is stored as a pair of edges of a directed compressed graph. Thus, what is typically understood as the number of hoppings would rather correspond to half that value.
- The number of sites of an infinite system does not correspond to the number of sites of the graph, since the graph contains "mirror" sites that are used to define inter-cell hoppings.
Both these points seem easy to fix. But we should also consider the planned evolution of Kwant. In our new vectorized system format the number of hoppings in the old sense is not even that easy to compute (since there can be multiple hoppings connecting the same sites).
Such pretty printed "representations" of systems must be very lossy. What is actually their purpose? To provide some useful statistics? To be able to tell different systems from each other? Something else?https://gitlab.kwant-project.org/kwant/kwant/-/issues/397Can Discretizer benefit from Sympy's common subexpression extraction feature?2020-11-19T12:25:14ZMichael WimmerCan Discretizer benefit from Sympy's common subexpression extraction feature?Can one use `sympy.cse` to optimize the expressions that `kwant.continuum.Discretizer` generates?Can one use `sympy.cse` to optimize the expressions that `kwant.continuum.Discretizer` generates?https://gitlab.kwant-project.org/kwant/kwant/-/issues/395Improve Hamiltonian evaluation for vectorized systems2020-10-26T15:23:39ZChristoph GrothImprove Hamiltonian evaluation for vectorized systemsSo far, the new `system.VectorizedSystem` offers a `hamiltonian_submatrix` method that offers a subset of the functionality of the eponymous method of `system.System`.
This is a good first step, but we are not bound by backwards compati...So far, the new `system.VectorizedSystem` offers a `hamiltonian_submatrix` method that offers a subset of the functionality of the eponymous method of `system.System`.
This is a good first step, but we are not bound by backwards compatibility here (the new `hamiltonian_submatrix` already breaks it), since there is no legacy code that enables vectorization.
This gives as a unique opportunity to modernize the API for evaluating Hamiltonians.
Here are some problems with the old API:
- It's incompatible with ND-systems.
- It's not possible to selectively evaluate terms (for example only terms that depend on a particular parameter could be of interest).
- By default, a dense matrix is returned (#244).
- It's impossible to act with the Hamiltonian on a vector without creating a sparse matrix in memory.
- `inter_cell_hopping` may return non-square matrices.vectorizationhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/122Emancipate sites from `builder`2020-10-23T15:58:20ZChristoph GrothEmancipate sites from `builder`Kwant is moving in a direction where sites and the associated families and symmetries are becoming first-class concepts that are independent of the builder module.
As a first step in this direction, let's move `Site`, `SiteFamily` and `...Kwant is moving in a direction where sites and the associated families and symmetries are becoming first-class concepts that are independent of the builder module.
As a first step in this direction, let's move `Site`, `SiteFamily` and `Symmetry` from `builder` into `system`. (the old names will have to remain usable for backwards compatibility.) `SimpleSiteFamily` can be also moved and perhaps renamed.
This will allow to make the `lattice` module independent of `builder`. This in turn will allow the use of concepts like `TranslationalSymmetry` inside the builder module (currently this is impossible due to circular imports.)
With site families independent of builders `VerySimpleSymmetry` can be replaced by `TranslationalSymmetry` in the builder tests.Kwant 1.5https://gitlab.kwant-project.org/kwant/kwant/-/issues/393Improve user experience when dealing with densities2020-10-23T15:46:27ZChristoph GrothImprove user experience when dealing with densitiesThe original Kwant made it quite easy to define TB systems in terms of sites and to evaluate transport properties like transmission probabilities between leads. In this workflow low-level systems and their inner workings were an impleme...The original Kwant made it quite easy to define TB systems in terms of sites and to evaluate transport properties like transmission probabilities between leads. In this workflow low-level systems and their inner workings were an implementation detail of Kwant.
When the operator module was added, it was natural for it to deal with low-level systems. However this meant that suddenly the user was exposed to details of low-level systems like the order of sites and their indices.
We would like to provide an intuitive way to handle densities, and the [vectorization effort](https://gitlab.kwant-project.org/kwant/kwant/-/milestones/9) seems like a good moment to introduce a new improved API because we have to [review operators for ND systems](#333) anyway.
To proposals exist that offer different solutions to this problem:
- #9
- #65
I propose to discuss the topic generally here and decide on a course of action. At the end of the discussion, one of the above two issues could be updated, and the other closed (along with this one).vectorizationhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/244hamiltonian_submatrix returns a dense matrix by default2020-10-23T15:37:26ZJoseph Westonhamiltonian_submatrix returns a dense matrix by defaultI think that `hamiltonian_submatrix` should, by default, return a sparse matrix.
Kwant's design is in several places predicated on the fact that tight-binding Hamiltonians are usually local, and hence their matrices are sparse.
If some...I think that `hamiltonian_submatrix` should, by default, return a sparse matrix.
Kwant's design is in several places predicated on the fact that tight-binding Hamiltonians are usually local, and hence their matrices are sparse.
If someone tries to call `hamiltonian_submatrix` for a relatively large system they will get a `MemoryError`. I believe that this is a problem for Kwant's UX.https://gitlab.kwant-project.org/kwant/kwant/-/issues/394Factor out `kwant.kpm`2020-10-23T09:41:18ZDániel VarjasFactor out `kwant.kpm`Anton suggested that it would be better in the long term to separate `kwant.kpm` in its own package, so other projects that rely on a general KPM implementation don't need to import all of kwant. This would also make it more transparent ...Anton suggested that it would be better in the long term to separate `kwant.kpm` in its own package, so other projects that rely on a general KPM implementation don't need to import all of kwant. This would also make it more transparent to add improvements to the KPM implementation that are independent of kwant (for example I'm working on implementing KPM in a non-orthogonal basis now, something that kwant doesn't support yet).
What do you think @anton-akhmerov @cwg @pablopiskunow ?https://gitlab.kwant-project.org/kwant/kwant/-/issues/65Arrays indexable by site/hopping2020-10-22T14:20:38ZJoseph WestonArrays indexable by site/hoppingOften users will calculate quantities defined over sites/hoppings.
Presently, they have to map high-level `Site` objects to the corresponding index using the `sites` list
in the system.
This is unnecessarily cumbersome given how o...Often users will calculate quantities defined over sites/hoppings.
Presently, they have to map high-level `Site` objects to the corresponding index using the `sites` list
in the system.
This is unnecessarily cumbersome given how often this issue comes up. What we would like to have instead
is an array-like object that can be indexed using sites:
```
ld = kwant.ldos(syst, ...)
ld[lat(0, 0)]
```
Similarly, objects that are defined on hoppings (e.g. `kwant.operator.Current`) could be indexed with
pairs of sites:
```
current = J(psi)
current[lat(0, 0), lat(0, 1)]
```
Also the wavefunction returned by kwant could be indexed by site and return a sub-array over the orbitals
on that site (this is related to #9)
I could imagine the following hierarchy:
```
class Indexable:
def __init__(self, syst, data):
pass
def _index(self, obj):
pass
def __getitem__(self, obj):
return data[self._index(obj)]
class SiteIndexable(Indexable):
# acts on arrays defined over all sites, indexable by site
# (_index returns an integer)
...
class HoppingIndexable(Indexable):
# acts on arrays defined over all hoppings (hoppings ordered
# in the same way as when we iterate over the graph), indexable by hopping
# (_index returns an integer)
...
class OrbitalIndexable(Indexable):
# acts on arrays defined over all orbitals, indexable by site
# (_index returns a slice over -- this can be obtained almost trivially
# from `syst.site_ranges` (see `_get_orbs` in `kwant/operator.pyx`))
...
```
future