Thanks!
This is exactly what I needed.

On Sat, Dec 17, 2016 at 4:31 AM, Joseph Weston <joseph.weston08@gmail.com> wrote:
Hi,

> I'm doing a self consistent calculation and I need the matrix element for a
> site when setting the coupling.
> I got it working but I wanted to know if there was a correct way.
> Here is my code which uses scipy.spatial.
>
> def onsite(site, Delta=None, coords=None):
>     if (Delta is None and coords is None):
>         Delta_r = Delta_0
>     else:
>         _, i = spatial.KDTree(coords).query(site.pos)
>         Delta_r = Delta[i]
>     return -mu * tau_z + Delta_r * tau_x

Ok, so you essentially need to map from site -> site_index in order to
index into your array, right? I guess the solution will depend on
whether your sites are moving around or not during your self-consistent
loop. My guess is "no", as you appear to be self-consistently
determining some superconducting order parameter, and I guess your sites
correspond to a discretisation of the continuous problem.

In this case I would say that the simplest thing to do would be to use
a `dict` data structure to do the mapping site -> site_index. The reason
is that lookups in a dict have O(1) complexity, unlike a KDTree. In
addition, this mapping can be constructed once, when the system is
finalized, and then passed to the `onsite` function as a parameter.

In Kwant 1.3 systems will have an attribute `id_by_site`, which stores
this dictionary, but constructing it is also trivial:

    id_by_site = {site: i for i, site in enumerate(syst.sites)}


So a full example would look like:

    def onsite(site, id_by_site, Delta=None):
        Delta_r = Delta_0 if Delta is None else Delta[id_by_site[site]]
        return -mu * tau_z + Delta_r * tau_x

    builder = kwant.Builder(...)
    builder[...] = onsite
    ...

    syst = builder.finalize()

    id_by_site = {site: i for i, site in enumerate(syst.sites)}
    Delta = [0.1] * len(syst.sites)  # trivial example
    ...
    syst.smatrix(syst, args=(id_by_site, Delta))


Hope that helps,

Joe