// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movl %edx, 0x2c(%rsp)
movq %rsi, %r14
movq %rdi, %rbx
xorpd %xmm0, %xmm0
leaq 0x50(%rsp), %rdi
movapd %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
movslq 0x110(%rsi), %rsi
leaq 0x30(%rsp), %rdx
orl $-0x1, (%rdx)
callq 0x36f18
xorpd %xmm0, %xmm0
movupd %xmm0, (%rbx)
andq $0x0, 0x10(%rbx)
movapd %xmm0, 0x30(%rsp)
andq $0x0, 0x40(%rsp)
movq 0x50(%rsp), %rax
andl $0x0, (%rax)
leaq 0xd0(%rsp), %rdx
andl $0x0, (%rdx)
leaq 0xa0(%rsp), %rdi
pushq $0x1
popq %rsi
leaq 0x88(%rsp), %rcx
callq 0x2a44a
leaq 0xa0(%rsp), %rsi
movq %rbx, %rdi
callq 0xad52
movq 0x2f0(%r14), %rax
movsd 0x18(%rax), %xmm0
movsd 0x20(%rax), %xmm1
movsd 0x28(%rax), %xmm2
leaq 0xd0(%rsp), %rdi
callq 0x6402e
leaq 0x88(%rsp), %rdi
leaq 0xd0(%rsp), %rdx
movl 0x2c(%rsp), %esi
callq 0x7a2a1
movq %rbx, 0x10(%rsp)
leaq 0x30(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0xc19b4
leaq 0x88(%rsp), %rdi
callq 0xb132
pushq $0x1
popq %rax
pushq $0x18
popq %r13
movl %eax, 0xc(%rsp)
cmpl 0x110(%r14), %eax
jge 0x7a13b
xorl %r12d, %r12d
movl %r12d, %ecx
movq 0x38(%rsp), %rax
subq 0x30(%rsp), %rax
cqto
idivq %r13
cmpq %rcx, %rax
jbe 0x7a06d
xorl %r15d, %r15d
imulq $0x18, %rcx, %rbp
movl %r15d, %r15d
movq 0x30(%rsp), %rdi
movq 0x8(%rdi,%rbp), %rax
subq (%rdi,%rbp), %rax
cqto
idivq %r13
cmpq %r15, %rax
jbe 0x7a058
addq %rbp, %rdi
movslq 0xc(%rsp), %rax
movq 0x2f0(%r14), %rcx
imulq $0x98, %rax, %rax
movsd (%rcx,%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x8(%rcx,%rax), %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0x10(%rcx,%rax), %xmm0
movsd %xmm0, 0x78(%rsp)
movq %r15, %rsi
callq 0x4b6d6
movsd (%rax), %xmm0
movsd %xmm0, 0x70(%rsp)
movq 0x30(%rsp), %rdi
addq %rbp, %rdi
movq %r15, %rsi
callq 0x4b6d6
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x68(%rsp)
movq 0x30(%rsp), %rdi
addq %rbp, %rdi
movq %r15, %rsi
callq 0x4b6d6
movsd 0x10(%rax), %xmm5
movq %r14, %rdi
movsd 0x20(%rsp), %xmm0
movsd 0x80(%rsp), %xmm1
movsd 0x78(%rsp), %xmm2
movsd 0x70(%rsp), %xmm3
movsd 0x68(%rsp), %xmm4
callq 0x3f56c
movapd %xmm0, %xmm1
incl %r15d
movsd 0x876f4(%rip), %xmm0    # 0x1016c0
ucomisd %xmm1, %xmm0
jbe 0x79ef7
movslq 0xc(%rsp), %r15
movq 0x2f0(%r14), %rbx
movq 0x10(%rsp), %rax
movq (%rax), %rdi
addq %rbp, %rdi
xorl %esi, %esi
movsd %xmm1, 0x20(%rsp)
callq 0xac00
imulq $0x98, %r15, %rcx
leaq (%rbx,%rcx), %rdi
addq $0x40, %rdi
movslq (%rax), %rax
movq 0x2f0(%r14), %rcx
imulq $0x98, %rax, %rax
leaq (%rcx,%rax), %rsi
addq $0x40, %rsi
callq 0x4bbbb
testb %al, %al
jne 0x7a1fd
movslq 0xc(%rsp), %rax
movq 0x50(%rsp), %rcx
movl %r12d, (%rcx,%rax,4)
movq 0x10(%rsp), %rax
addq (%rax), %rbp
movq %rbp, %rdi
leaq 0xc(%rsp), %rsi
callq 0x9434
movsd 0x20(%rsp), %xmm1
incl %r12d
movsd 0x8765d(%rip), %xmm0    # 0x1016c0
ucomisd %xmm1, %xmm0
jbe 0x79ed5
ucomisd 0x8764b(%rip), %xmm1    # 0x1016c0
movl 0xc(%rsp), %eax
leaq 0xb8(%rsp), %r15
jb 0x7a134
movsd %xmm1, 0x20(%rsp)
movslq %eax, %rcx
movq 0x38(%rsp), %rax
subq 0x30(%rsp), %rax
cqto
idivq %r13
movq 0x50(%rsp), %rdx
movl %eax, (%rdx,%rcx,4)
movslq 0xc(%rsp), %rax
movq 0x2f0(%r14), %rcx
imulq $0x98, %rax, %rax
movsd 0x18(%rcx,%rax), %xmm0
movsd 0x20(%rcx,%rax), %xmm1
movsd 0x28(%rcx,%rax), %xmm2
leaq 0x88(%rsp), %rbx
movq %rbx, %rdi
callq 0x6402e
movq %r15, %rdi
movl 0x2c(%rsp), %esi
movq %rbx, %rdx
callq 0x7a2a1
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0xc19b4
movq %r15, %rdi
callq 0xb132
movq %r15, %rdi
pushq $0x1
popq %rsi
leaq 0xc(%rsp), %rdx
leaq 0x1f(%rsp), %rcx
callq 0x2a44a
movq 0x10(%rsp), %rdi
movq %r15, %rsi
callq 0xad52
movq %r15, %rdi
callq 0xb290
movl 0xc(%rsp), %eax
movsd 0x20(%rsp), %xmm1
incl %eax
jmp 0x79ec1
xorl %r14d, %r14d
movq 0xd5e7b(%rip), %rbx     # 0x14ffc0
leaq 0x8ba97(%rip), %r12     # 0x105be3
leaq 0x8ba97(%rip), %r15     # 0x105bea
leaq 0x88424(%rip), %rbp     # 0x10257e
movl %r14d, %r14d
movq 0x10(%rsp), %rcx
movq 0x8(%rcx), %rax
subq (%rcx), %rax
cqto
idivq %r13
cmpq %r14, %rax
jbe 0x7a1c5
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4480
movq %rax, %rdi
movq %r14, %rsi
callq 0x42e0
movq %rax, %rdi
movq %r15, %rsi
callq 0x4480
movq 0x10(%rsp), %rcx
movq (%rcx), %rcx
imulq $0x18, %r14, %rdx
movq 0x8(%rcx,%rdx), %rsi
subq (%rcx,%rdx), %rsi
sarq $0x2, %rsi
movq %rax, %rdi
callq 0x42e0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x4480
incl %r14d
jmp 0x7a15a
leaq 0xa0(%rsp), %rdi
callq 0xb290
leaq 0x30(%rsp), %rdi
callq 0x4bf94
leaq 0x50(%rsp), %rdi
callq 0xb290
movq 0x10(%rsp), %rax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xd5dec(%rip), %rdi     # 0x14fff0
leaq 0x8b995(%rip), %rsi     # 0x105ba0
callq 0x4480
pushq $0x1
popq %rdi
callq 0x524c
movq %rax, %r14
leaq 0x88(%rsp), %rdi
jmp 0x7a25b
jmp 0x7a229
jmp 0x7a229
movq %rax, %r14
jmp 0x7a270
movq %rax, %r14
jmp 0x7a27d
movq %rax, %r14
jmp 0x7a28f
movq %rax, %r14
leaq 0xb8(%rsp), %rdi
callq 0xb290
jmp 0x7a26b
jmp 0x7a268
jmp 0x7a268
jmp 0x7a268
movq %rax, %r14
leaq 0xb8(%rsp), %rdi
callq 0xb132
jmp 0x7a26b
jmp 0x7a268
jmp 0x7a268
jmp 0x7a268
movq %rax, %r14
movq 0x10(%rsp), %rbx
leaq 0xa0(%rsp), %rdi
callq 0xb290
leaq 0x30(%rsp), %rdi
callq 0x4bf94
movq %rbx, %rdi
callq 0xad7e
leaq 0x50(%rsp), %rdi
callq 0xb290
movq %r14, %rdi
callq 0x4780