// File: /workspace/github_c_makefile_star2_O3/ugobas[P]tnm/kinetic_tnm.c
// Function: Reorient_axes
void Reorient_axes(atom *atoms, int N_atoms, struct Reference Ref)
{
  double **inertia_tot=Allocate_mat2_d(3,3);
  double **corr_sum=Allocate_mat2_d(3,3);
  double r_ave[3], mr_tot[3]; int i, k, l;

  // Compute inertia tensor and center of mass for all atoms
  for(i=0; i<3; i++)mr_tot[i]=0;
  double M_tot=Sum_inertia(mr_tot, corr_sum, atoms, Ref, 0, Ref.N_ref-1);
  for(i=0; i<3; i++)r_ave[i]=mr_tot[i]/M_tot;
  Inertia_tensor(inertia_tot, corr_sum, mr_tot, M_tot);
  float eigen_value[3], **rot=Allocate_mat2_f(3, 3);
  d_Diagonalize(3, inertia_tot, eigen_value, rot, 1);
  float det=Det_33(rot);
  printf("Determinant= %.3f\n", det);
  if(det<0){
    k=0;
    while(k<3){
      for(l=0; l<3; l++)rot[k][l]=-rot[k][l];
      det=Det_33(rot); if(det>0)break;
      for(l=0; l<3; l++)rot[k][l]=-rot[k][l];
      k++;
    }
    printf("Determinant= %.3f\n", det);
  }

  if(0){
    printf("Center of mass: ");
    for(i=0; i<3; i++)printf("  %.7f", r_ave[i]);
    printf("  M=%.1f\n", M_tot);
    printf("Inertia_values: ");
    for(k=0; k<3; k++)printf(" %.0f", eigen_value[k]);
    printf("\n");
    printf("Rotation matrix:\n");
    for(k=0; k<3; k++){
      for(l=0; l<3; l++)printf(" %.3f", rot[k][l]);
      printf("\n");
    }
  }

  // Rotate atoms coordinates
  for(i=0; i<N_atoms; i++){
    double rr[3], *r=atoms[i].r;
    for(k=0; k<3; k++){
      //double rk=0; for(l=0; l<3; l++)rk+=rot[k][l]*r[l]; rr[k]=rk;
      rr[k]=rot[k][0]*r[0]+rot[k][1]*r[1]+rot[k][2]*r[2];
    }
    for(k=0; k<3; k++)r[k]=rr[k];
  }

  if(0){
    // Test that inertia tensor is diagonal
    for(i=0; i<3; i++)mr_tot[i]=0;
    M_tot=Sum_inertia(mr_tot, corr_sum, atoms, Ref, 0, Ref.N_ref-1);
    Inertia_tensor(inertia_tot, corr_sum, mr_tot, M_tot);
    d_Diagonalize(3, inertia_tot, eigen_value, rot, 1);
    printf("Principal axes:\n");
    for(k=0; k<3; k++){
      float *v=rot[k];
      for(l=0; l<3; l++)printf(" %.3f", v[l]);
      printf("\n");
    }
    exit(8);
  }

  Empty_matrix_d(corr_sum, 3);
  Empty_matrix_d(inertia_tot, 3);
  Empty_matrix_f(rot, 3);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %esi, %ebp
movq %rdi, %r14
movl $0x3, %edi
movl $0x3, %esi
callq 0x49804
movq %rax, %rbx
movl $0x3, %edi
movl $0x3, %esi
callq 0x49804
movq %rax, %r15
xorpd %xmm0, %xmm0
movapd %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
movslq 0x90(%rsp), %rax
testq %rax, %rax
jle 0x233c0
movq 0xa0(%rsp), %rcx
movq 0xb8(%rsp), %rdx
xorpd %xmm0, %xmm0
xorl %esi, %esi
movslq (%rdx,%rsi,4), %rdi
imulq $0x70, %rdi, %rdi
addq %r14, %rdi
xorps %xmm1, %xmm1
cvtss2sd (%rcx,%rsi,4), %xmm1
xorl %r8d, %r8d
movsd (%rdi,%r8,8), %xmm2
mulsd %xmm1, %xmm2
cvtsd2ss %xmm2, %xmm2
cvtss2sd %xmm2, %xmm2
movsd 0x10(%rsp,%r8,8), %xmm3
addsd %xmm2, %xmm3
movsd %xmm3, 0x10(%rsp,%r8,8)
movq (%r15,%r8,8), %r9
movq %r8, %r10
movsd (%rdi,%r10,8), %xmm3
mulsd %xmm2, %xmm3
addsd (%r9,%r10,8), %xmm3
movsd %xmm3, (%r9,%r10,8)
incq %r10
cmpq $0x3, %r10
jne 0x23382
incq %r8
cmpq $0x3, %r8
jne 0x23357
addsd %xmm1, %xmm0
incq %rsi
cmpq %rax, %rsi
jne 0x23341
cvtsd2ss %xmm0, %xmm0
cvtss2sd %xmm0, %xmm0
jmp 0x233c3
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x226ac
movl $0x3, %edi
movl $0x3, %esi
callq 0x4971a
movq %rax, %r12
leaq 0x4c(%rsp), %rdx
movl $0x3, %edi
movq %rbx, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x4a559
movq %r12, %rdi
callq 0x2355a
movss %xmm0, 0xc(%rsp)
cvtss2sd %xmm0, %xmm0
leaq 0x35589(%rip), %rdi     # 0x589a2
movb $0x1, %al
callq 0x20f0
xorps %xmm0, %xmm0
ucomiss 0xc(%rsp), %xmm0
jbe 0x234a7
movl %ebp, 0xc(%rsp)
xorl %r13d, %r13d
movaps 0x2dbf8(%rip), %xmm2    # 0x51030
movq (%r12,%r13,8), %rbp
xorl %eax, %eax
movss (%rbp,%rax,4), %xmm0
xorps %xmm2, %xmm0
movss %xmm0, (%rbp,%rax,4)
incq %rax
cmpq $0x3, %rax
jne 0x2343e
movq %r12, %rdi
callq 0x2355a
movaps 0x2dbcb(%rip), %xmm2    # 0x51030
ucomiss 0x2dcac(%rip), %xmm0    # 0x51118
ja 0x23491
xorl %eax, %eax
movss (%rbp,%rax,4), %xmm1
xorps %xmm2, %xmm1
movss %xmm1, (%rbp,%rax,4)
incq %rax
cmpq $0x3, %rax
jne 0x23470
incq %r13
cmpq $0x3, %r13
jne 0x23438
cvtss2sd %xmm0, %xmm0
leaq 0x35506(%rip), %rdi     # 0x589a2
movb $0x1, %al
callq 0x20f0
movl 0xc(%rsp), %ebp
testl %ebp, %ebp
jle 0x23524
movl %ebp, %eax
xorl %ecx, %ecx
imulq $0x70, %rcx, %rsi
leaq (%r14,%rsi), %rdx
movsd (%r14,%rsi), %xmm0
movsd 0x8(%r14,%rsi), %xmm1
movsd 0x10(%r14,%rsi), %xmm2
xorl %esi, %esi
movq (%r12,%rsi,8), %rdi
xorps %xmm3, %xmm3
cvtss2sd (%rdi), %xmm3
mulsd %xmm0, %xmm3
xorps %xmm4, %xmm4
cvtss2sd 0x4(%rdi), %xmm4
mulsd %xmm1, %xmm4
addsd %xmm3, %xmm4
xorps %xmm3, %xmm3
cvtss2sd 0x8(%rdi), %xmm3
mulsd %xmm2, %xmm3
addsd %xmm4, %xmm3
movsd %xmm3, 0x30(%rsp,%rsi,8)
incq %rsi
cmpq $0x3, %rsi
jne 0x234cd
movq 0x40(%rsp), %rsi
movq %rsi, 0x10(%rdx)
movaps 0x30(%rsp), %xmm0
movups %xmm0, (%rdx)
incq %rcx
cmpq %rax, %rcx
jne 0x234af
movq %r15, %rdi
movl $0x3, %esi
callq 0x496ae
movq %rbx, %rdi
movl $0x3, %esi
callq 0x496ae
movq %r12, %rdi
movl $0x3, %esi
callq 0x49678
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq