Giter Club home page Giter Club logo

Comments (2)

pablosanjose avatar pablosanjose commented on June 3, 2024

There is a very important issue that can arise in the approach above: the interpolated set of eigenstates at a given ϕs does not form an orthogonal basis. I can imagine this could give problems when computing observables.

This doesn't mean that the general algorithm is invalid, it just might need to be modified. It essentially consists of two distinct elements: (1) degenerate eigenvalues carry a full basis of their degenerate space for purposes of connecting band vertices, and (2) simplices have eigenstates that do not need to be vertex-unique when compared with neighboring simplices.

To solve the Dirac-point issue, what we actually need is (1), which resolves frustrations in the connectivity. We could dispense with (2), in fact. Once connected, we can actually choose vertex-unique states in degenerate subspaces. They might simply not be too similar to the other vertex states in a given simplex with vertex degeneracies. Interpolation of eigenstates will thus not be very smooth. This is inevitable in Dirac points, but not in trivial band crossings, where velocity codiagonalization is optimal.

So I see two options to achieve a sane bandstructure with simplex-unique states: keep (1) and the current codiagonalization pass, dropping the last two paragraph in the OP above, or keep (1) and adapt the projection step, dropping the codiagonalization. I'm inclined towards the latter.

How would it go? First we would never do copies of degenerate vertex subspaces. This way we have a built-in guarantee that all vertices end up with unique eigenstates, because all transformations we do of subspace states are shared between vertices. We can transform these subspaces in any way we want and, as long as in the end we have different degenerate vertices pick at the end a different column of their space (which will remain orthogonal) we're good. So the crucial change, apart from never doing copies of states, is to know how to transform subspaces at simplex-collection time. The ideal would be to be able to have views with shuffled columns, and use the first one as the axis to align. Views don't support that, but we can create a new wrapper for views that holds the desired alignement column for each vertex (i.e. store the shift of the circshift above together with the view, without copying.).

So all steps above will proceed the same, except for replacing the circshift with a wrapper of a view basis and the shift, renamed to axis (and adapting proj to unwrap basis, of course). At the end of step 3, however, we wish to do the following:

  • When populating svecs we will be processing simplices in the same order they appear in each band, which implies that they are order by the first vertex.
  • Take the first least-degenerate subspace and reduce its basis to a view of the column given by its axis (no copies). This will be the reference vector vref to align the simplex
  • We now iterate over the remaining subspaces (vertices in the simplex). For a given subspace, we compute the projection vproj of vref on its basis
  • We build a permutation P_axis that reorders the basis, so that basis*P_axis simply switches the axis vector to the first column in basis
  • We build a matrix A = hcat(vproj, basis*P_axis) whose first two columns are vproj and the axis vector. Its rank is the same as basis, since the added vproj is a linear combination of basis.
  • We do a QR decomposition of a matrix A. The Q matrix obtained is the new orthonormal basis of the subspace we're after. Its first vector is proportional to vproj, and the rest are orthonormal, but not randomly so.
  • We now just need to rewrite basis with Q, but first we have to move the first column back to position axis, which is done with the transpose of P_axis. We do basis .= Q * P_axis'. Note that this modifies the parent array that basis points to. We don't need to do anything else, as the basis, axis wrapper for the vertex in question is not modified, only the parent array is.
  • Finally, we take a view(basis, :, axis) as the 1D SubArray for the vertex. Note that this is equal to vproj but the preceding steps are necessary to update also the rest of the basis, to keep it orthonormal for all vertices in the same vertex stack.

This is quite a nice method, because it guarantees a unique (and maximally continuous?) sampling of the eigenstate manifold, even in the non-Abelian case of degenerate . This might still have dislocations and jumps, but they will be unavoidable. The one loose end I see is the choice of vref on each simplex. I think it is fine, but I worry about the edge case in which the first vertex of a simplex has higher degeneracy than the rest, which are still degenerate. Then, vref might have a completely random orientation (if that vertex has not been visited and aligned before). Its orientation will thus propagate to any later simplex connected to the first, even if at a later step the random vref gets aligned with some other lower-degeneracy vertex. But I'm not sure what the consequences of this might be. I'll have to check.

from quantica.jl.

pablosanjose avatar pablosanjose commented on June 3, 2024

While implementing this proposal I've realized that the complexity of organizing band simplices into groups with the same base simplex (the sptr array) is tricky to implement clearly and efficiently. It is much easier to classify them simply by base minicuboid (i.e. little D-dimensional cubes made of D! base mesh simplices). This implies making sptr::Array{UnitRante{Int},D} instead of sptr::Array{UnitRante{Int},D+1}.

Marching meshes have the property that the minicuboid a simplex belongs to can be identified by the "lower left corner". That is, all simplices in a minicuboid share a vertex that can be found as the first in the simplex list of vertices when sorted lexicographically (this is not true of other meshings). Then, sorting simplices into minicuboids is straightforward. Accessing them with bs[(ϕs...)] is also straightforward, as one just needs to find the mincuboid that contains (ϕs...), which is trivial. The price is that one will need to check D! times more simplices to find the ones contributing to bs[(ϕs...)], but that is O(1), and it might actually be faster because, crucially, we don't need to keep and search an ImmutableDict to do translations of vertex groups to simplex indices in a given minicuboid. We do a linear lookup of all simplices in the minicuboid instead, which for D<=3 might be more efficient.

from quantica.jl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.