Page 1 of 1

Ordering of bisection localization vector

Posted: Fri Nov 20, 2020 2:07 am
by andyx
Hi users,

a. I'd like to understand the ordering of the localization vector in the bisection printout -- from left to right, is the ordering all the x first, then y, then z? Or is it x, y, z, x, y, z, ...?

For example, suppose we choose blHF = 2 3 1 with a simulation cell of 1 x 1 x 1 for simplicity, and the localization vector is (bunch of zeros)010111111001. Would this correspond to the following (going from left to right) -- 01 meaning localized [0.5, 1] in x direction; 01 meaning localized [0.5, 0.75] (which means right bit corresponds to where Walsh function is 1) in x (or is it [0.75, 1], meaning right bit corresponding to whichever segment is "more to the right"?), 11 meaning still localized [0, 1] in y, 11 meaning localized [0, 1] in y, 10 meaning localized [0.125, 0.375] and [0.625, 0.875] in y, and 01 meaning localized in [0.5, 1] in z?

b. I'd like to see if I can compare localization vectors.

Specifically, assuming I use the same blHF and same simulation cell size, would I be able to compare the localization vectors between the orbitals of different systems to tell if they overlap in each subdomain, since the same blHF and cell size should mean that the subdomains exactly correspond to each other?

Re: Ordering of bisection localization vector

Posted: Sat Nov 21, 2020 12:44 am
by fgygi
The total number of Walsh projectors used in the bisection process is nlevels[0]+nlevels[1]+nlevels[2], where the values of nlevels are the 3 values of the blHF variable, or the first 3 arguments of the bisection command.

The Walsh projectors are ordered by level and by direction (x,y,z). Thus for nlevels = (2,2,2), the projectors are:
level 0, x
level 0, y
level 0, z
level 1, x
level 1, y
level 1, z

The description of the localization of each orbital (after bisection) is given by two bits for each projector. The two bits describe whether the orbital is localized on the region where the projector is 0 (the "zero side", bit pair=(10)), the region where the projector is 1 (the "one side", bit pair=(01)), or both regions (bit pair=(11)). Note that the combination (00) cannot occur. The bits are packed in a localization vector that consists of a 64 bit integer. The logic of the construction of the localization vector is best explained by the corresponding code in function Bisection::compute_localization in Bisection.cpp:

Code: Select all

void Bisection::compute_localization(double epsilon)
{
  // compute localization vector for a threshold epsilon
  for ( int n = 0; n < nst_; n++ )
  {
    localization_[n] = 0;
    for ( int imat = 0; imat < nmat_; imat++ )
    {
      if ( adiag_[imat][n] < epsilon )
        localization_[n] += 1<<(2*imat);
      else if ( adiag_[imat][n] > 1.0-epsilon)
        localization_[n] += 1<<(2*imat+1);
      else
        localization_[n] += (1<<(2*imat)) + (1<<(2*imat+1));
    }
  }
where the index imat runs overs all projectors. The first projector (level 0, x) is represented by the two least significant bits of the localization vector. The second projector (level 0, y) is represented by the next two bits, and so on.

Example: After performing a bisection using the bisection 2 2 2 0.01 command for a 64-molecule water sample, the localization vector of orbital 244 (counting starting from 0) is printed on output as

Code: Select all

localization[244]: 2491 000000000000000000100110111011 size: 0.0625 overlaps: 36
This shows that this orbital is (starting from the least significant bits):
- delocalized across both sides of the (level 0, x) projector (bits 11)
- localized on the 0 side of the (level 0, y) projector (bits 10)
- delocalized across both sides of the (level 0, z) projector (bits 11)
- localized on the 0 side of the (level 1, x) projector (bits 10)
- localized on the 1 side of the (level 1, y) projector (bits 01)
- localized on the 0 side of the (level 1, z) projector (bits 10).
All the following (00) pairs are indicating an absence of projectors. Localization vectors are always represented a a full 64 bit string.

The value 0.0625 indicates the fraction of the unit cell on which the orbital is localized: each "successful" bisection by a projector (i.e. yielding bit pairs 10 or 01) contributes a factor 1/2. The total number of "successful" projectors in this example is 4, so that the size is 1/2**4 = 1/16 = 0.0625. This orbital overlaps with 36 other orbitals.
Note that the localization vector, the size, and the number of overlapping orbitals depend on the value of the threshold used. In the limit of small threshold, all the bit pairs become (11).

For comparison of localization of orbitals in different systems, note that the localization vector specifies a subdomain of the unit cell. If two orbitals have different localization vectors, it is possible to determine whether they overlap using the Bisection::overlap function in Bisection.cpp:

Code: Select all

bool Bisection::overlap(const vector<long int>& loc_, int i, int j) const
{
  // overlap: return true if the functions i and j overlap according
  // to the localization vector loc_
  long int loc_i = loc_[i];
  long int loc_j = loc_[j];
  while ( loc_i!=0 && loc_j!=0 )
  {
    // get the weight of projections for each state
    bool p_right_i = loc_i & 1;
    bool p_left_i  = loc_i & 2;
    bool p_right_j = loc_j & 1;
    bool p_left_j  = loc_j & 2;

    // return false as soon as the states are found to be separated
    if ( !( ( p_right_i && p_right_j ) || ( p_left_i && p_left_j ) ) )
      return false;

    loc_i >>= 2;
    loc_j >>= 2;
  }

  // return true if the states overlap
  return true;
}

Re: Ordering of bisection localization vector

Posted: Tue Nov 24, 2020 12:26 am
by andyx
Thank you very much Francois!

Re: Ordering of bisection localization vector

Posted: Wed Nov 25, 2020 4:02 am
by andyx
Hi users,

I'm a bit confused about the pair fraction.

I bisected the orbitals of a water dimer in Qbox 1.71.4, and got the following:

Code: Select all

 BisectionCmd: lx=3 ly=3 lz=3 threshold=0.02
localization[0]: 170750 000000000000101001101011111110 size: 0.01562 overlaps: 5
localization[1]: 178879 000000000000101011101010111111 size: 0.03125 overlaps: 8
localization[2]: 170750 000000000000101001101011111110 size: 0.01562 overlaps: 5
localization[3]: 174783 000000000000101010101010111111 size: 0.01562 overlaps: 4
localization[4]: 170750 000000000000101001101011111110 size: 0.01562 overlaps: 5
localization[5]: 174783 000000000000101010101010111111 size: 0.01562 overlaps: 4
localization[6]: 170750 000000000000101001101011111110 size: 0.01562 overlaps: 5
localization[7]: 174783 000000000000101010101010111111 size: 0.01562 overlaps: 4
 Bisection: total size:    ispin=0: 0.01758
 Bisection: pair fraction: ispin=0: 0.5556
 Bisection: time=0.5916
Since the pair fraction tells us the number of pairs that need to be computed if we were to calculate the exact exchange If we sum the overlaps, that will count the elements on the diagonal once and all the elements off the diagonal twice.

Summing all the overlaps gives 40. The pairs involving different orbitals is over-counted, so the numerator of the pair fraction is (sum of overlaps - nbnd)/2 + nbnd = (40 - 8)/2 + 8 = 24.

There are 8*9/2 = 36 total pairs, so shouldn't the pair fraction be 0.66?