Builder parameter substitution
Since Kwant 1.3 builders can be used as "models" to fill()
other (lower symmetry) builders. This way of working nicely complements traditional ways of system construction in Kwant and it allows for expressive code, see for example the example script that came with "What's new in 1.3".
However, try to add onsite disorder to that example. There's currently no good way to do it. If you create a single model with a U(x, y)
parameter, the only way I can think of is to precalculate the leads, but this is not satisfactory as a general solution.
To make things worse, some users of Kwant may have the idea to define U(x, y)
such that it's disordered where the scattering region is and flat where the leads are. However, this will not work as intended (most of the time), since value functions are evaluated in the fundamental domain.
The best current solution that I can think of is to create two "models", one that has a U_flat
parameter, and one that has a U(x, y)
parameter. But this is obviously ugly.
We could try to solve this problem on the level of the discretizer module, but I think that it is more general (models can be created in other ways, e.g. manually or from some ab-initio calculations). That's why I suggest to provide a way to substitute parameters of a builder. The API could be like this:
model = ...
syst = kwant.Builder()
syst.fill(model, syst_shape, (0, 0))
lead = kwant.Builder(sym)
lead.fill(model.subs(U='U_lead'), lead_shape, (0, 0))
syst.attach_lead(lead)
syst = syst.finalized()
kwant.wave_function(syst, params=dict(U=function, U_lead=0.1))
For the above to work, two things are needed:
- A
Builder.subs()
method and some way for builders to internally store value functions with substitutions. - Discretizer must be extended to accept numbers for "function" parameters. That should be easy.
For the value function substitutions, I propose to create a new callable class that can be derived from tuple and stores `(function, ((old_name1, new_name1), (old_name1, new_name1))). The fact that it's callable will make this new functionality compatible with existing code that knows only about two kinds of builder values: callable value functions and non-callable constants. Of course the class should be intelligent enough to avoid nesting itself. Also, code in Builder can treat it specially.
Please comment!