kwant issueshttps://gitlab.kwant-project.org/kwant/kwant/-/issues2023-05-05T17:45:01Zhttps://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/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/372Use structural subtyping for defining interfaces to the different parts of Kwant2020-04-01T16:46:58ZJoseph WestonUse structural subtyping for defining interfaces to the different parts of Kwant## Problem definition
In principle Kwant has several more or less independent components separated by interfaces: Builder, System, solvers, plotter
In practice the specific interfaces that are used are only loosely defined, and it is q...## Problem definition
In principle Kwant has several more or less independent components separated by interfaces: Builder, System, solvers, plotter
In practice the specific interfaces that are used are only loosely defined, and it is quite challenging (even for one well-versed in the internals of Kwant) to create new classes which adhere to the correct interface.
Take, for example `kwant.system.FiniteSystem` which can, in principle, be plotted by `kwant.plot` if it provides a `pos` method (this is not even documented in the docstring of `plot`; it just says that the `sys` parameter may be a `Builder` or `system.Finitesystem`). However, if the leads do not provide a `symmetry` attribute that has the interface of a `kwant.lattice.TranslationalSymmetry` then they are simply not plotted.
This is not documented in `plot`. Even if it were, having ad-hoc interfaces defined in docstrings is probably not the way to go.
In practice people use Kwant as a monolithic package, and it is often unacceptable to e.g. be able to define custom system classes but be unable to plot them properly.
## Proposed Solution
I propose to use structural subtyping a la [PEP 544](https://www.python.org/dev/peps/pep-0544) to allow use to more precisely specify the interfaces required by the different parts of Kwant.
We can either wait until we can rely on Python 3.8, and make use of [`typing.Protocol`](https://docs.python.org/3/library/typing.html#typing.Protocol) or roll our own with `__subclass_hook__`.https://gitlab.kwant-project.org/kwant/kwant/-/issues/334Extend Kwant to work with overlap matrices2019-11-21T09:46:54ZJoseph WestonExtend Kwant to work with overlap matricesIn some contexts people want to solve `Hψ = ESψ` where `S` is an overlap matrix. Two examples that come to mind are: tight-binding models that have been obtained from an ab-initio calculation and the Hamiltonian is expressed in a non-ort...In some contexts people want to solve `Hψ = ESψ` where `S` is an overlap matrix. Two examples that come to mind are: tight-binding models that have been obtained from an ab-initio calculation and the Hamiltonian is expressed in a non-orthogonal basis, discretization on Finite-Element-Method meshes.
Currently we assume that `S` is the identity matrix, and this is assumption is actually encoded pretty deeply in some parts of Kwanthttps://gitlab.kwant-project.org/kwant/kwant/-/issues/333Review vectorized operators in light of ND systems2020-10-22T14:20:37ZJoseph WestonReview vectorized operators in light of ND systemsvectorizationhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/322Review whether builder interface can be vectorized2019-10-15T08:06:07ZAnton AkhmerovReview whether builder interface can be vectorizedWith vectorized systems being much faster, constructing them still will stay slow (actually slower than before). We should at least consider constructing vectorizing the system construction interface.With vectorized systems being much faster, constructing them still will stay slow (actually slower than before). We should at least consider constructing vectorizing the system construction interface.vectorizationhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/316implement vectorized ND systems2020-05-08T14:11:30ZAnton Akhmerovimplement vectorized ND systemsRequires also:
- finalization of ND systems
- Reimplementing modes, optionally taking a tuple of extra momenta if the system has more than 1 translation symmetry.
- Making `spectrum` work with these.
- Plotting
The format change will a...Requires also:
- finalization of ND systems
- Reimplementing modes, optionally taking a tuple of extra momenta if the system has more than 1 translation symmetry.
- Making `spectrum` work with these.
- Plotting
The format change will also remove the extra sites, mentioned in [this discussion](https://gitlab.kwant-project.org/kwant/kwant/merge_requests/323/#note_32200).vectorizationhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/309documentation reorganization2019-07-16T13:23:36ZAnton Akhmerovdocumentation reorganizationI'll expand on this, but here's a note from the discussion with @michaelwimmer and @jbweston
![image](/uploads/81a7872e991a37e9f0b716d02bf5b831/image.png)I'll expand on this, but here's a note from the discussion with @michaelwimmer and @jbweston
![image](/uploads/81a7872e991a37e9f0b716d02bf5b831/image.png)https://gitlab.kwant-project.org/kwant/kwant/-/issues/284lead.modes fails at band opening for 1D chain2020-09-29T18:54:10ZBenoit Rossignollead.modes fails at band opening for 1D chainWhen I try to compute the modes close to band opening/closing of a 1D lead I get the error
```
ValueError: Input a needs to be a square matrix.
```
This is problematic because
1. It only happens with 1D lead (for want I have see)
2. E...When I try to compute the modes close to band opening/closing of a 1D lead I get the error
```
ValueError: Input a needs to be a square matrix.
```
This is problematic because
1. It only happens with 1D lead (for want I have see)
2. Every time I want to compute quantities (transmission, etc) I have to adjust manually the energy ranges to avoid this problem or use try/except
Simple example:
A lead of dimension D
```
lat = kwant.lattice.square(norbs=1)
lead = kwant.Builder(kwant.TranslationalSymmetry((1, 0)))
for y in range(D):
lead[lat(0, y)] = 4
lead[lat.neighbors()] = -1
l = lead.finalized()
```
The problem
```
bands = kwant.physics.Bands(l)
for e in bands(np.pi):
l.modes(e)
for e in bands(0):
l.modes(e)
```
I never got any problem for D > 1, it always fails for D = 1.https://gitlab.kwant-project.org/kwant/kwant/-/issues/177Incorporate bound state finding algorithm2019-02-09T22:04:35ZAnton AkhmerovIncorporate bound state finding algorithmRelevant reference: [1711.08250](https://arxiv.org/abs/1711.08250).Relevant reference: [1711.08250](https://arxiv.org/abs/1711.08250).futurehttps://gitlab.kwant-project.org/kwant/kwant/-/issues/127fill() is not atomic2018-09-20T08:12:06ZChristoph Grothfill() is not atomicWhen `fill` fails, because `max_sites` is reached or because the shape function raises an exception (this happens in `attach_lead()` when the scattering region does not interrupt the central builder), the graph of the target builder is i...When `fill` fails, because `max_sites` is reached or because the shape function raises an exception (this happens in `attach_lead()` when the scattering region does not interrupt the central builder), the graph of the target builder is in an inconsistent state and is currently erased.
`fill` should be atomic: either it suceeds, or it leaves `self` untouched.Kwant 1.5Christoph GrothChristoph Grothhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/81providing params via system interface2020-05-08T21:02:13ZAnton Akhmerovproviding params via system interfaceAfter #77 the call signature of `kwant.smatrix` and other consumers of `System` have a rather lengthy call signature: `kwant.smatrix(syst, energy, args=..., params=...)`. It is counter-intuitive to supply arguments that the system consum...After #77 the call signature of `kwant.smatrix` and other consumers of `System` have a rather lengthy call signature: `kwant.smatrix(syst, energy, args=..., params=...)`. It is counter-intuitive to supply arguments that the system consumes using awkward syntax and via an unrelated function.
I propose an alternative pathway for doing so. A method `System.update_parameters(*args, **kwargs)` that will return a shallow copy of the system that stores its arguments and keyword arguments such that the user doesn't need to provide them elsewhere. Example usage:
```python
[kwant.smatrix(syst.update_parameters(0, B=5)) for B in fields]
```
Extra considerations
* `System`s already have a method `precalculate` that returns a modified shallow copy.
* This change is fully backwards-compatible (old way of providing parameters would still work).futurehttps://gitlab.kwant-project.org/kwant/kwant/-/issues/73Base lattices on the concept of symmetry2019-02-09T22:09:31ZChristoph GrothBase lattices on the concept of symmetryKwant contains both the concept of spatial symmetries and the concept of regular (Bravais) lattices. Both are related: `TranslationalSymmetry` works only with the lattices as defined in the `lattice` module.
This integration could be...Kwant contains both the concept of spatial symmetries and the concept of regular (Bravais) lattices. Both are related: `TranslationalSymmetry` works only with the lattices as defined in the `lattice` module.
This integration could be improved. For example, the flood-fill code of `shape()` in the lattice module and `fill()` in the builder module is similar. It should be possible to redefine lattices on top of (translational?) symmetries, and factor out as much common code as possible.futurehttps://gitlab.kwant-project.org/kwant/kwant/-/issues/51Take advantage of keyword-only arguments2017-06-23T12:59:54ZChristoph GrothTake advantage of keyword-only argumentsPython 3 offers keyword-only arguments. We should take advantage of them to keep the API cleaner and more future-proof. Functions often have arguments that are used only sporadically or that are mutually exclusive. When these are decl...Python 3 offers keyword-only arguments. We should take advantage of them to keep the API cleaner and more future-proof. Functions often have arguments that are used only sporadically or that are mutually exclusive. When these are declared as keyword-only arguments, the door remains open to add further positional arguments in the future.
This issue is about hunting down all relevant cases in the Kwant API and modifying it accordingly. This should be done by introducing new names (e.g. `kwant.lattice.square2`), except in cases where problems due to backwards incompatibility are highly improbable.
An example:
Currently, we have `kwant.lattice.square(a=1, name='')`. Now we want to add the number of orbitals as an additional obligatory parameter. Respecting backwards compatibility, we can only do this in the following way: `kwant.lattice.square(a=1, name='', num_orbs=None)`. This will make specifying `num_orbs` cumbersome.
Both `a` and `name` are not used much. Had both been defined as keyword-only args `kwant.lattice.square(*, a=1, name='')`, we could have simply added `num_orbs` as a new positional parameter: `kwant.lattice.square(num_orbs, *, a=1, name='')`Kwant 2https://gitlab.kwant-project.org/kwant/kwant/-/issues/46Distinguish public and internal interfaces (not only in documentation)2019-02-09T22:04:34ZChristoph GrothDistinguish public and internal interfaces (not only in documentation)Motivation
----------
Even though Python is a language for "consenting adults", it's still good to help users not to shoot in their foot, by making it clear what is part of the public API and what is internal.
PEP 8 says: "Public ...Motivation
----------
Even though Python is a language for "consenting adults", it's still good to help users not to shoot in their foot, by making it clear what is part of the public API and what is internal.
PEP 8 says: "Public attributes are those that you expect unrelated clients of your class to use, with your commitment to avoid backward incompatible changes. Non-public attributes are those that are not intended to be used by third parties; you make no guarantees that non-public attributes won't change or even be removed."
We have been trying to do that, but Kwant is still behind what PEP 8 recommends and what good libraries (like the stdlib) do. The aim of this proposal is to make Kwant join this illustrious circle.
Global-level functions
----------------------
We have been careful to put global names that belong to the API into `__all__` variables. In addition to that, PEP 8 recommends to use leading underscores for internal global names in parallel with `__all__`: "Even with `__all__` set appropriately, internal interfaces (packages, modules, classes, functions, attributes or other names) should still be prefixed with a single leading underscore."
I think this is good practice, since it makes it immediately clear to a user what belongs to the API.
Kwant has plenty of global-level functions that are not part of the API (= not included in `__all__`) and whose names do not begin with underscores. Some examples:
`lattice.short_array_repr()`,
`builder.validate_hopping()`,
`plotter.set_colors()`,
`physics.leads.setup_linsys()`,
`linalg.lll.gs()`
All of the above (and the many other similar ones) should be perpended with underscores.
Methods
-------
I'm quite confident that the names of methods in Kwant do not require any changes. Because there's no `__all__` for classes we have been using underscores already.
Types
-----
Internal types that do not have to be known by the user should get an underscore, e.g.:
`kwant.solvers.common.WaveFunction`,
`kwant.builder.FiniteSystem`
Non-public instance variables
-----------------------------
PEP 8 is quite clear: "Use one leading underscore only for non-public methods and instance variables."
It’s reasonable that internal should be the default (PEP 8 also says so). Some examples of instance variables that are clearly internal:
`solvers.mumps.Solver`: `nrhs`,
`lattice.Polyatomic`: `reduced_vecs`,
`builder.Builder`: `H`
Note that a class with only non-public instance variables becomes effectively immutable if none of its public methods provides a way to modify the instance. Kwant’s lattice types are good examples of classes that should be effectively immutable, but are currently lacking the corresponding leading underscores.
Public instance variables
-------------------------
When an instance could be useful for external clients, and we can commit ourselves to keep it around, we can define is as part of the public API by (a) documenting it and (b) leaving out the leading underscore. A good example is `sites` of finalized builders. A somewhat less clear is `symmetry` of builders. I think the latter could be useful, and we are sure to have to keep the symmetry around, so why not make it part of the API?
I think it’s important to make it easy and safe to use public instance variables. I think a reasonable approach is to either make sure that they are immutable (example: `sites` of finalized builders), or to treat them as external parameters (example: `leads` of builders). If mutation is allowed, the rules should be documented, and we should make sure that there is a clear-enough error message if these rules are violated (often duck typing will be enough).
Write-protecting public instance variables
------------------------------------------
Users are allowed to modify the `leads` attribute of builders. It's even OK to assign somthing new to it. If that something is bogus, it won't lead to silent corruption of the builders state, because `leads` is treated as just another parameter to `finalized()`.
On the other hand, the `sites` instance variable of a finalized builder is clearly a part of the internal state. It is immutable, and its elements are effectively immutable as well, but a user could still simply assign some wrong value to it: `fsyst.sites = bogus_list`.
It's not difficult to imagine situations where this will lead to confusing errors.
We could choose not to care about such situations, but it actually is common among proper Python libraries to do so. The following idiom occurs more than 100 times in the stdlib:
```
@property
def foo(self)
return self._foo
```
I propose to do the same and make public instance variables properties, whenever reassigning them risks making the internal state inconsistent. This rules out attributes like `leads` of builders (consistency is not endangered), or attributes of simple container classes, e.g. the error message of an exception.
futurehttps://gitlab.kwant-project.org/kwant/kwant/-/issues/34Clarify docstring of kwant.physics.StabilizedModes2020-10-22T09:10:26ZChristoph GrothClarify docstring of kwant.physics.StabilizedModesThe second paragraph needs to be expanded and reformulated to clearly specify what the various attributes contain.The second paragraph needs to be expanded and reformulated to clearly specify what the various attributes contain.futurehttps://gitlab.kwant-project.org/kwant/kwant/-/issues/29Factor out MUMPS2019-02-08T16:28:52ZAnton AkhmerovFactor out MUMPSMost of the work we've done in porting MUMPS makes more sense as a standalone MUMPS wrapper. [pymumps](https://github.com/bfroehle/pymumps) is a related project, that implements a smaller subset of MUMPS interface. We could also consider...Most of the work we've done in porting MUMPS makes more sense as a standalone MUMPS wrapper. [pymumps](https://github.com/bfroehle/pymumps) is a related project, that implements a smaller subset of MUMPS interface. We could also consider using the way scipy wraps BLAS and LAPACK a model approach.Kwant 1.5https://gitlab.kwant-project.org/kwant/kwant/-/issues/23Consistent separation of left-, right-propagating and evanescent modes2020-09-29T18:54:10ZAnton AkhmerovConsistent separation of left-, right-propagating and evanescent modesRight now if a new propagating mode opens, Kwant may count one mode out of the pair as propagating, another one as evanescent due to numerical errors. It should be relatively easy to enforce consistency by using that evanescent modes alw...Right now if a new propagating mode opens, Kwant may count one mode out of the pair as propagating, another one as evanescent due to numerical errors. It should be relatively easy to enforce consistency by using that evanescent modes always come in pairs `λ` `1/λ^*`.
The relevant code is in the `make_proper_modes` function [over here](kwant/physics/leads.py#L405).Kwant 1.5Anton AkhmerovAnton Akhmerovhttps://gitlab.kwant-project.org/kwant/kwant/-/issues/22Stability of lead modes calculation2019-02-09T22:09:31ZAnton AkhmerovStability of lead modes calculationWhile Schur decomposition works well in general, it seems to fail for some Hamiltonians. The example people encounter most frequently is Kane-Mele model on a zigzag ribbon at zero energy. Another important example is [Kwant_QZ_iteration_...While Schur decomposition works well in general, it seems to fail for some Hamiltonians. The example people encounter most frequently is Kane-Mele model on a zigzag ribbon at zero energy. Another important example is [Kwant_QZ_iteration_failed.ipynb](/uploads/cc67fc9e8e9ffed2579f163ff5697f79/Kwant_QZ_iteration_failed.ipynb) because that system fails at many different energies. Maximilian Trescher reported this issue [over here](http://thread.gmane.org/gmane.comp.science.kwant.user/460)
It isn't at all obvious whether we can improve on stability in these cases, but identifying what happens would also be important.futurehttps://gitlab.kwant-project.org/kwant/kwant/-/issues/20Finding the optimal unit cell2018-05-01T12:24:25ZAnton AkhmerovFinding the optimal unit cellFor systems with a complex hopping graph, a smart choice of the unit cell reduces the number of hoppings connecting different unit cells, and speeds up the further calculations. We could adapt some version of mincut algorithm to perform ...For systems with a complex hopping graph, a smart choice of the unit cell reduces the number of hoppings connecting different unit cells, and speeds up the further calculations. We could adapt some version of mincut algorithm to perform the optimization of the unit cell shape automatically on attaching or finalization. This may lead to a non-trivial interplay with issue #4 (neat attaching of leads).
Action Steps
------------
A master student in Grenoble (Adrien Sorgniard) implemented Karger's mincut algorithm that minimises the unit cell interface, however the code is not in a merge-worthy state. The person looking to address this issue will need to take the code that he has written, understand it, and modify it so that it is of merge-able quality.
This will involve:
- [x] getting Adrien's code from his Kwant fork
- understanding the algorithms used (Karger algorithm)
- understanding Adrien's implementation
- [ ] adding comments / refactoring the code where necessary to make it readable
- [ ] adding tests, especially for edge cases