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) Ok, so you essentially need to map from site -> site_index in order to
> Delta_r = Delta[i]
> return -mu * tau_z + Delta_r * tau_x
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