// File: Luthaf[P]zeopp/symmetry.cc
// Function: IdentifyEquivalentAtoms(ATOM_NETWORK&, int)
vector < vector<int> >  IdentifyEquivalentAtoms(ATOM_NETWORK &atomNet, int spacegroup)
{
  vector <int> AtomGroup; AtomGroup.resize(atomNet.numAtoms,-1); // for each atom stores information if it waswas assigned to a group
  vector < vector<int> > Groups;
  vector < vector<XYZ> > EqPosGroup;

  // First atom sets a new group of atoms equivalent by position

  AtomGroup[0]=0;
  vector <int> v(1,0);
  Groups.push_back(v);
  XYZ at(atomNet.atoms[0].a_coord, atomNet.atoms[0].b_coord, atomNet.atoms[0].c_coord);
  EqPosGroup.push_back(GetEquivalentPositions(spacegroup,&at));

  // Second and other atoms
  for(int i=1; i<atomNet.numAtoms; i++)
    {
    double dist;

    for(unsigned int gr=0; gr<EqPosGroup.size(); gr++) 
      {
      for(unsigned int pos=0; pos<EqPosGroup[gr].size(); pos++)
         {
         dist=atomNet.calcDistanceXYZABC(atomNet.atoms[i].x,atomNet.atoms[i].y,atomNet.atoms[i].z,
                                    EqPosGroup[gr].at(pos).x,EqPosGroup[gr].at(pos).y,EqPosGroup[gr].at(pos).z);
         if(dist<TOLERANCE) 
            {
            if(atomNet.atoms[i].type!=atomNet.atoms[Groups[gr].at(0)].type)
              {
              cerr << "Atoms of different types occupy positions equivalent by symmetry.\n";
              exit(1); 
              };
            AtomGroup[i]=gr;
            Groups[gr].push_back(i);
            break;
            };
         };
         if(dist<TOLERANCE) break; // leave the outer loop if equivalent position was found
      }; // outer loop 

    if(dist>=TOLERANCE) // if dist larger than TOLERANCE, equivalent position has not been found and a new group of equivalent position is to be created
      {
      AtomGroup[i]=EqPosGroup.size();
      XYZ at(atomNet.atoms[i].a_coord, atomNet.atoms[i].b_coord, atomNet.atoms[i].c_coord);
      EqPosGroup.push_back(GetEquivalentPositions(spacegroup,&at));
      vector <int> v(1,i);
      Groups.push_back(v);
      };

    }; // loop other all atoms


 // Print Symmetry group summary 
 for(unsigned int i=0; i<Groups.size(); i++)
   {
   cout << "Group " << i << "  size= " << Groups[i].size() << "\n";
   };

  return Groups; 

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movq %rdi, -0x130(%rbp)
movq %rdi, %rax
movq %rax, -0x128(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
leaq -0x30(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0xd0d0
movq -0x120(%rbp), %rdi
movq -0x10(%rbp), %rax
movslq 0x110(%rax), %rsi
movl $0xffffffff, -0x34(%rbp) # imm = 0xFFFFFFFF
leaq -0x34(%rbp), %rdx
callq 0x84b00
jmp 0x11743b
movq -0x130(%rbp), %rdi
movb $0x0, -0x45(%rbp)
callq 0x10580
leaq -0x60(%rbp), %rdi
callq 0xafd80
xorl %eax, %eax
movl %eax, %esi
leaq -0x30(%rbp), %rdi
callq 0xed60
movl $0x0, (%rax)
movl $0x0, -0x7c(%rbp)
leaq -0x7d(%rbp), %rdi
movq %rdi, -0x138(%rbp)
callq 0x10960
movq -0x138(%rbp), %rcx
leaq -0x78(%rbp), %rdi
movl $0x1, %esi
leaq -0x7c(%rbp), %rdx
callq 0x65a70
jmp 0x117499
leaq -0x7d(%rbp), %rdi
callq 0x13030
movq -0x130(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x107f0
jmp 0x1174b4
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x150(%rbp)
callq 0xfcc0
movq -0x150(%rbp), %rsi
movsd 0x18(%rax), %xmm0
movsd %xmm0, -0x148(%rbp)
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
callq 0xfcc0
movq -0x150(%rbp), %rsi
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x140(%rbp)
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
callq 0xfcc0
movsd -0x148(%rbp), %xmm0
movsd -0x140(%rbp), %xmm1
movsd 0x28(%rax), %xmm2
leaq -0x98(%rbp), %rdi
callq 0xea8e0
jmp 0x11753a
movl -0x14(%rbp), %esi
leaq -0xb0(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x117c50
jmp 0x117552
leaq -0x60(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x16f730
jmp 0x117564
leaq -0xb0(%rbp), %rdi
callq 0x12210
movl $0x1, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x110(%rcx), %eax
jge 0x117ae4
movl $0x0, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
movq %rax, -0x158(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xbb260
movq %rax, %rcx
movq -0x158(%rbp), %rax
cmpq %rcx, %rax
jae 0x11791b
movl $0x0, -0xc8(%rbp)
movl -0xc8(%rbp), %eax
movq %rax, -0x160(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0xbb620
movq %rax, %rdi
callq 0xae590
movq %rax, %rcx
movq -0x160(%rbp), %rax
cmpq %rcx, %rax
jae 0x1178f1
movq -0x10(%rbp), %rdi
movq %rdi, -0x188(%rbp)
addq $0x2f0, %rdi            # imm = 0x2F0
movslq -0xb4(%rbp), %rsi
callq 0xfcc0
movsd (%rax), %xmm0
movsd %xmm0, -0x180(%rbp)
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
movslq -0xb4(%rbp), %rsi
callq 0xfcc0
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x178(%rbp)
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
movslq -0xb4(%rbp), %rsi
callq 0xfcc0
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x170(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0xbb620
movq %rax, %rdi
movl -0xc8(%rbp), %eax
movl %eax, %esi
callq 0xae5c0
movq %rax, -0x168(%rbp)
jmp 0x1176a2
movq -0x168(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x198(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0xbb620
movq %rax, %rdi
movl -0xc8(%rbp), %eax
movl %eax, %esi
callq 0xae5c0
movq %rax, -0x190(%rbp)
jmp 0x1176df
movq -0x190(%rbp), %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x1a8(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0xbb620
movq %rax, %rdi
movl -0xc8(%rbp), %eax
movl %eax, %esi
callq 0xae5c0
movq %rax, -0x1a0(%rbp)
jmp 0x11771d
movsd -0x1a8(%rbp), %xmm4
movsd -0x198(%rbp), %xmm3
movsd -0x170(%rbp), %xmm2
movsd -0x178(%rbp), %xmm1
movsd -0x180(%rbp), %xmm0
movq -0x188(%rbp), %rdi
movq -0x1a0(%rbp), %rax
movsd 0x10(%rax), %xmm5
callq 0x978a0
movsd %xmm0, -0x1b0(%rbp)
jmp 0x117767
movsd -0x1b0(%rbp), %xmm0
movsd %xmm0, -0xc0(%rbp)
movsd 0xe00e1(%rip), %xmm0    # 0x1f7860
ucomisd -0xc0(%rbp), %xmm0
jbe 0x1178db
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
movslq -0xb4(%rbp), %rsi
callq 0xfcc0
movq -0x130(%rbp), %rdi
addq $0x40, %rax
movq %rax, -0x1c8(%rbp)
movq -0x10(%rbp), %rax
addq $0x2f0, %rax            # imm = 0x2F0
movq %rax, -0x1c0(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, %esi
callq 0x10890
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x101d0
movq %rax, -0x1b8(%rbp)
jmp 0x1177e9
movq -0x1c0(%rbp), %rdi
movq -0x1b8(%rbp), %rax
movslq (%rax), %rsi
callq 0xfcc0
movq -0x1c8(%rbp), %rdi
movq %rax, %rsi
addq $0x40, %rsi
callq 0xaf490
testb $0x1, %al
jne 0x117818
jmp 0x117890
movq 0x15b7d1(%rip), %rdi    # 0x272ff0
leaq 0xe7312(%rip), %rsi     # 0x1feb38
callq 0x5540
jmp 0x11782d
movl $0x1, %edi
callq 0x67c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x117c2f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x7d(%rbp), %rdi
callq 0x13030
jmp 0x117bf3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x117bea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x12210
jmp 0x117bea
movl -0xc4(%rbp), %eax
movl %eax, -0x1cc(%rbp)
movslq -0xb4(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0xed60
movl -0x1cc(%rbp), %ecx
movq -0x130(%rbp), %rdi
movl %ecx, (%rax)
movl -0xc4(%rbp), %eax
movl %eax, %esi
callq 0x10890
movq %rax, %rdi
leaq -0xb4(%rbp), %rsi
callq 0xd1b0
jmp 0x1178d9
jmp 0x1178f1
jmp 0x1178dd
movl -0xc8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc8(%rbp)
jmp 0x1175cd
movsd 0xdff67(%rip), %xmm0    # 0x1f7860
ucomisd -0xc0(%rbp), %xmm0
jbe 0x117905
jmp 0x11791b
jmp 0x117907
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0x11759a
movsd -0xc0(%rbp), %xmm0
movsd 0xdff35(%rip), %xmm1    # 0x1f7860
ucomisd %xmm1, %xmm0
jb 0x117ace
leaq -0x60(%rbp), %rdi
callq 0xbb260
movl %eax, -0x1e4(%rbp)
movslq -0xb4(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0xed60
movl -0x1e4(%rbp), %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
movslq -0xb4(%rbp), %rsi
callq 0xfcc0
movsd 0x18(%rax), %xmm0
movsd %xmm0, -0x1e0(%rbp)
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
movslq -0xb4(%rbp), %rsi
callq 0xfcc0
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x1d8(%rbp)
movq -0x10(%rbp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
movslq -0xb4(%rbp), %rsi
callq 0xfcc0
movsd -0x1e0(%rbp), %xmm0
movsd -0x1d8(%rbp), %xmm1
movsd 0x28(%rax), %xmm2
leaq -0xe0(%rbp), %rdi
callq 0xea8e0
jmp 0x1179de
movl -0x14(%rbp), %esi
leaq -0xf8(%rbp), %rdi
leaq -0xe0(%rbp), %rdx
callq 0x117c50
jmp 0x1179f6
leaq -0x60(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x16f730
jmp 0x117a08
leaq -0xf8(%rbp), %rdi
callq 0x12210
leaq -0x111(%rbp), %rdi
movq %rdi, -0x1f0(%rbp)
callq 0x10960
movq -0x1f0(%rbp), %rcx
leaq -0x110(%rbp), %rdi
movl $0x1, %esi
leaq -0xb4(%rbp), %rdx
callq 0x65a70
jmp 0x117a48
leaq -0x111(%rbp), %rdi
callq 0x13030
movq -0x130(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x107f0
jmp 0x117a69
leaq -0x110(%rbp), %rdi
callq 0xec80
jmp 0x117ace
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x12210
jmp 0x117bea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x111(%rbp), %rdi
callq 0x13030
jmp 0x117bea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x110(%rbp), %rdi
callq 0xec80
jmp 0x117bea
jmp 0x117ad0
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x11757a
movl $0x0, -0x118(%rbp)
movq -0x130(%rbp), %rdi
movl -0x118(%rbp), %eax
movq %rax, -0x1f8(%rbp)
callq 0x10860
movq %rax, %rcx
movq -0x1f8(%rbp), %rax
cmpq %rcx, %rax
jae 0x117bcc
movq 0x15b49f(%rip), %rdi    # 0x272fc0
leaq 0xe7053(%rip), %rsi     # 0x1feb7b
callq 0x5540
movq %rax, -0x200(%rbp)
jmp 0x117b36
movq -0x200(%rbp), %rdi
movl -0x118(%rbp), %esi
callq 0x56f0
movq %rax, -0x208(%rbp)
jmp 0x117b51
movq -0x208(%rbp), %rdi
leaq 0xe7023(%rip), %rsi     # 0x1feb82
callq 0x5540
movq %rax, -0x210(%rbp)
jmp 0x117b6d
movq -0x130(%rbp), %rdi
movl -0x118(%rbp), %eax
movl %eax, %esi
callq 0x10890
movq %rax, %rdi
callq 0x10090
movq -0x210(%rbp), %rdi
movq %rax, %rsi
callq 0x5160
movq %rax, -0x218(%rbp)
jmp 0x117ba1
movq -0x218(%rbp), %rdi
leaq 0xe1a76(%rip), %rsi     # 0x1f9625
callq 0x5540
jmp 0x117bb6
jmp 0x117bb8
movl -0x118(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x118(%rbp)
jmp 0x117aee
movb $0x1, -0x45(%rbp)
leaq -0x78(%rbp), %rdi
callq 0xec80
leaq -0x60(%rbp), %rdi
callq 0xafe50
testb $0x1, -0x45(%rbp)
jne 0x117c16
jmp 0x117c0a
leaq -0x78(%rbp), %rdi
callq 0xec80
leaq -0x60(%rbp), %rdi
callq 0xafe50
movq -0x130(%rbp), %rdi
callq 0x108b0
jmp 0x117c2f
movq -0x130(%rbp), %rdi
callq 0x108b0
leaq -0x30(%rbp), %rdi
callq 0xec80
movq -0x128(%rbp), %rax
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0xec80
movq -0x40(%rbp), %rdi
callq 0x58f0
nopw %cs:(%rax,%rax)