// File: /workspace/github_c_makefile_star2_O2/ugobas[P]tnm/kinetic_tnm.c
// Function: Compute_kinetic
int Compute_kinetic(struct Jacobian *J,
		    struct axe *axe1, int naxe1,
		    atom *atoms1, int natoms1,
		    struct Reference Ref, int SQR)
{
  int N_kin=0;
  int test=(J->Jacobian_ar[0][0]==0);
  // Put center of mass at the origin
  Center_atoms(atoms1, natoms1, Ref);
  // Reorient the Cartesian axes along the principal axes
  //Reorient_axes(atoms1, natoms1, Ref);

  Set_rot_shift(axe1, naxe1, atoms1, natoms1);
  Eckart_main(axe1, naxe1, atoms1, natoms1, Ref);
  Internal_Jacobian(*J, Ref, atoms1, natoms1, axe1, naxe1);
  if(test){
    Eckart_test(J->Jacobian_ar, naxe1, atoms1, natoms1, Ref, axe1);
    if(0)Correlate_Jacobian(*J, Ref, axe1, naxe1);
  }
  Kinetic_energy_fast(J, axe1, naxe1, atoms1, natoms1, Ref);
  //Kinetic_energy_Jac(*J, Ref, naxe1);

  if(SQR){
    // Compute T_sqrt with Cholevsky decomposition
    // Empty matrices
    if(J->T_sqrt_inv){
      Empty_matrix_f(J->T_sqrt_inv, naxe1); J->T_sqrt_inv=NULL;
    }
    if(J->T_sqrt_inv_tr!=NULL){
      Empty_matrix_f(J->T_sqrt_inv_tr, naxe1); J->T_sqrt_inv_tr=NULL;
    }
    if(J->T_sqrt_tr!=NULL){
      Empty_matrix_f(J->T_sqrt_tr, N_kin); J->T_sqrt_tr=NULL;
    }
    if(J->Jtilde_ar!=NULL){
      Empty_matrix_f(J->Jtilde_ar, naxe1); J->Jtilde_ar=NULL;
    }

    // Compute T_sqrt with Cholevsky decomposition
    Kinetic_sqrt(J, &(N_kin), naxe1, T_COMPUTE, E_MIN);    
    // Transpose matrix to accelerate computation
    if(J->T_sqrt_inv){
      J->T_sqrt_inv_tr=Transpose_matrix(J->T_sqrt_inv, N_kin, naxe1);
    }else{
      J->T_sqrt_tr=Transpose_matrix_d2f(J->T_sqrt, N_kin, N_kin);
    }
  }
  J->N_kin=N_kin;

  // Show results
  if(DBG){
    int i, j, m=10;
    printf("Masses: ");
    for(i=0; i<3*m; i+=3)printf("%.0f ", Ref.mass_coord[i]);
    printf("\nJacobian: ");
    for(i=0; i<m; i++)printf("%.1f ", J->Jacobian_ar[i][0]);
    printf("\nKinetic energy matrix. ");
    printf("%d dofs atoms= %d cart= %d Nkin= %d\n",
	   naxe1, natoms1, Ref.N_Cart, N_kin);
    for(i=0; i<m; i++){
      for(j=0; j<m; j++)printf("%.2g\t", J->T_sqrt[i][j]);
      printf("\n");
    }
    printf("Axis properties\n");
    struct axe *axe=axe1;
    for(i=0; i<30; i++){
      printf("%c%d\t%s-%s\t%d-%d\t%d-%d\t%.2g\t%.2g\t%.2g\t%.2g\t%.2g\n",
	     axe->type, i,
	     axe->bond->previous->atom->name, axe->bond->atom->name,
	     axe->first_atom, axe->last_atom,
	     axe->first_kin, axe->last_kin,
	     axe->rot[0],
	     axe->local_shift[0], axe->local_rot[0],
	     axe->global_shift[0], axe->global_rot[0]);
      axe++;
    }
  }
  START=0;

  return(N_kin);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movl %r9d, 0x7c(%rsp)
movl %r8d, %r12d
movq %rcx, %r13
movl %edx, %r15d
movq %rsi, %rbx
movq %rdi, %r14
andl $0x0, 0x84(%rsp)
leaq 0xc0(%rsp), %rbp
movq 0x10(%rdi), %rax
movq (%rax), %rax
movss (%rax), %xmm0
movss %xmm0, 0x80(%rsp)
movaps (%rbp), %xmm0
movaps 0x10(%rbp), %xmm1
movaps 0x20(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rcx, %rdi
movl %r8d, %esi
callq 0x1ef40
movq %rbx, %rdi
movl %r15d, %esi
movq %r13, %rdx
callq 0x1f004
movaps (%rbp), %xmm0
movaps 0x10(%rbp), %xmm1
movaps 0x20(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rbx, %rdi
movl %r15d, %esi
movq %r13, %rdx
callq 0x1f2dd
pushq $0x9
popq %rcx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movaps (%rbp), %xmm0
movaps 0x10(%rbp), %xmm1
movaps 0x20(%rbp), %xmm2
movups %xmm2, 0x68(%rsp)
movups %xmm1, 0x58(%rsp)
movups %xmm0, 0x48(%rsp)
movq %r13, %rdi
movq %rbx, %rdx
movl %r15d, %ecx
callq 0x1fa58
xorps %xmm0, %xmm0
movss 0x80(%rsp), %xmm1
ucomiss %xmm0, %xmm1
jne 0x1ec97
jp 0x1ec97
movq 0x10(%r14), %rdi
movups (%rbp), %xmm0
movups 0x10(%rbp), %xmm1
movups 0x20(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl %r15d, %esi
movq %r13, %rdx
movl %r12d, %ecx
movq %rbx, %r8
callq 0x1fbc4
movups (%rbp), %xmm0
movups 0x10(%rbp), %xmm1
movups 0x20(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %r14, %rdi
movq %rbx, %rsi
movl %r15d, %edx
movq %r13, %rcx
callq 0x1fc6d
cmpl $0x0, 0x7c(%rsp)
je 0x1ed6c
movq 0x30(%r14), %rdi
testq %rdi, %rdi
je 0x1ece3
movl %r15d, %esi
callq 0x436f0
andq $0x0, 0x30(%r14)
movq 0x38(%r14), %rdi
testq %rdi, %rdi
leaq 0xc0(%rsp), %r13
je 0x1ed01
movl %r15d, %esi
callq 0x436f0
andq $0x0, 0x38(%r14)
movq 0x40(%r14), %rdi
testq %rdi, %rdi
je 0x1ed16
xorl %esi, %esi
callq 0x436f0
andq $0x0, 0x40(%r14)
movq 0x18(%r14), %rdi
testq %rdi, %rdi
je 0x1ed2c
movl %r15d, %esi
callq 0x436f0
andq $0x0, 0x18(%r14)
leaq 0x453c1(%rip), %rax     # 0x640f4
movss (%rax), %xmm0
leaq 0x84(%rsp), %rsi
movq %r14, %rdi
movl %r15d, %edx
xorl %ecx, %ecx
callq 0x200ce
movq 0x30(%r14), %rdi
testq %rdi, %rdi
je 0x1ed78
movl 0x84(%rsp), %ebp
movl %ebp, %esi
movl %r15d, %edx
callq 0x202be
movq %rax, 0x38(%r14)
jmp 0x1ed90
xorl %ebp, %ebp
leaq 0xc0(%rsp), %r13
jmp 0x1ed90
movq 0x28(%r14), %rdi
movl 0x84(%rsp), %ebp
movl %ebp, %esi
movl %ebp, %edx
callq 0x2030e
movq %rax, 0x40(%r14)
movl %ebp, 0x7c(%rsp)
movl %ebp, 0x8(%r14)
cmpl $0x0, 0x55569(%rip)     # 0x74308
je 0x1ef23
movl %r12d, 0x80(%rsp)
leaq 0x3377c(%rip), %rdi     # 0x52530
xorl %r12d, %r12d
xorl %eax, %eax
callq 0x20f0
movq 0x18(%r13), %rbp
leaq 0x33770(%rip), %r13     # 0x52539
cmpq $0x1d, %r12
ja 0x1ede6
cvtss2sd (%rbp,%r12,4), %xmm0
movq %r13, %rdi
movb $0x1, %al
callq 0x20f0
addq $0x3, %r12
jmp 0x1edc9
leaq 0x33752(%rip), %rdi     # 0x5253f
xorl %r12d, %r12d
xorl %eax, %eax
callq 0x20f0
leaq 0x2dbc5(%rip), %r13     # 0x4c9c3
movl 0x80(%rsp), %ebp
cmpq $0xa, %r12
je 0x1ee26
movq 0x10(%r14), %rax
movq (%rax,%r12,8), %rax
cvtss2sd (%rax), %xmm0
movq %r13, %rdi
movb $0x1, %al
callq 0x20f0
incq %r12
jmp 0x1ee05
leaq 0x3371e(%rip), %rdi     # 0x5254b
xorl %r13d, %r13d
xorl %eax, %eax
callq 0x20f0
leaq 0xc0(%rsp), %rax
movl 0x4(%rax), %ecx
leaq 0x3371b(%rip), %rdi     # 0x52564
movl %r15d, %esi
movl %ebp, %edx
movl 0x7c(%rsp), %r8d
xorl %eax, %eax
callq 0x20f0
pushq $0xa
popq %rbp
leaq 0x33725(%rip), %r15     # 0x52589
cmpq $0xa, %r13
je 0x1ee9c
xorl %r12d, %r12d
cmpq $0xa, %r12
je 0x1ee90
movq 0x28(%r14), %rax
movq (%rax,%r13,8), %rax
movsd (%rax,%r12,8), %xmm0
movq %r15, %rdi
movb $0x1, %al
callq 0x20f0
incq %r12
jmp 0x1ee6d
movl %ebp, %edi
callq 0x2060
incq %r13
jmp 0x1ee64
leaq 0x33a72(%rip), %rdi     # 0x52915
callq 0x2090
xorl %ebp, %ebp
leaq 0x336de(%rip), %r14     # 0x5258f
cmpl $0x1e, %ebp
je 0x1ef23
movsbl (%rbx), %esi
movq 0x8(%rbx), %rax
movq (%rax), %r8
movq 0x28(%rax), %rax
movq (%rax), %rcx
addq $0x18, %rcx
addq $0x18, %r8
movl 0x10(%rbx), %r9d
movl 0x14(%rbx), %eax
movl 0x18(%rbx), %edx
movl 0x1c(%rbx), %edi
movsd 0x48(%rbx), %xmm0
movsd 0xc0(%rbx), %xmm1
movsd 0xd8(%rbx), %xmm2
movsd 0x90(%rbx), %xmm3
movsd 0xa8(%rbx), %xmm4
movl %edi, 0x10(%rsp)
movl %edx, 0x8(%rsp)
movl %eax, (%rsp)
movq %r14, %rdi
movl %ebp, %edx
movb $0x5, %al
callq 0x20f0
addq $0x158, %rbx            # imm = 0x158
incl %ebp
jmp 0x1eeb1
andl $0x0, 0x44f82(%rip)     # 0x63eac
movl 0x7c(%rsp), %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq