Behaviour of lattice.find_coupling_pairs()

How do I use this algorithm? What does that parameter do?
Post Reply
SanJ
Posts: 1
Joined: 26 Apr 2023, 16:53

Behaviour of lattice.find_coupling_pairs()

Post by SanJ »

I have been using find_coupling_pairs to add couplings between all sites. However, I find the docs slightly misleading. Suppose we are dealing with a 2D orthonormal basis. From
max_dx (int) – Maximal index for each index of dx to iterate over. You need large enough values to include every possible coupling up to the desired distance, but choosing it too large might make this function run for a long time.
I would expect it to return pairs with dx = [max_dx, max_dx]. However, a quick look at the source code shows that a maximum distance of max_dx is enforced.

Is that the intended behaviour? If so, in which situations would it be useful? I feel that letting the cutoff parameter deal with distance independently of max_dx would be easier to work with.
User avatar
Johannes
Site Admin
Posts: 428
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Behaviour of lattice.find_coupling_pairs()

Post by Johannes »

Maybe the misleading thing is that we provide default parameter for cutoff.

This function is supposed to help in case you define a new Lattice and want to find some useful pairs to define. Of course, finding the nearest- and next-nearest neighbor pairs is still quite easy, but when you reach fourth- or fifth- neighbor pairs, it already becomes coumbersome and error-prone to do this by hand.
The use case why we implemented this function was that we wanted to simulate Rydberg atoms with dipolar interactions (decaying as 1/r^3) on various geometries. Given that the interaction decays with distance, we put a cutoff of a maximum distance, where we could estimate that 1/r^3 is already negligibly small such that we can ignore further-range interactions (and nevertheless check convergence of our final results with the cutoff...)

That use case layed out, let me comment on max_dx vs cutoff:
First, note that it can be different units, cutoff is in the units of the Lattice.basis and Lattice.unit_cell_positions, which determine the actual location of the sites in space, given just the integer numbers of the dx, so there's an overall scaling with the "lattice constant" how ever you choose that. In many cases, it's convenient to choose the lattice constant as the distance between nearest neighbors, but that might not be the length of the dx=[1,0,0] vector, depending on your lattice geometry. (In our use case, we used actual nanonmeters of the lab frame...)
Second, if you only point is getting all indices (x,y) with -max_dx <= x,y <= max_dx, you should just use itertools.product, np.indices or similar.
The real parameter you should choose is up to which cutoff you want the pairs - and then choose dx large enough to really include all dx up to that distance.
The dx is just technical, in the sense that we try all possible values of those dx for the returned result, and it gets more and more computationally expensive with increasing dx (since we check all combinations of possible pairs, it grows quickly!).

I hope that clarified things....
Post Reply